EF6 多对多关系添加时重复条目
EF6 Many-to-Many Relation Duplicate Entries on Add
我的数据在 Exhibitions
和 Markets
之间存在多对多关系。
创建新展览时,应将一些现有市场分配给它。
我创建了一个通用存储库,如下所示:
public virtual TDto Create(TDto data)
{
TEntity entity = ToEntity(data);
DbEntityEntry<TEntity> dbEntity = Context.Entry<TEntity>(entity);
dbEntity.State = EntityState.Added;
UpdateReferences(data, dbEntity);
Context.SaveChanges();
data = ToModel(dbEntity.Entity);
return data;
}
想法是允许每个具体存储库定义它自己的处理方式,以更新它对其他实体的引用。
protected override void UpdateReferences(Exhibition model, DbEntityEntry<Model.EventManagement.Exhibition> entity)
{
entity.Entity.Markets = new List<Model.EventManagement.Market>();
foreach (var market in model.Markets)
{
var marketEntity = Context.Markets.Single(m => m.Id == market.Id);
entity.Entity.Markets.Add(marketEntity);
}
}
出现的问题是,当我创建一个包含已有市场的新展览时,关联的市场会重复。我的上下文使用以下设置:
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
所以,我的问题是如何说服 EF 关联现有市场,而不是创建重复的市场?
我阅读了很多有关将 ID 属性与导航属性一起使用以避免此类问题的文章,但是对于多对多关系,这似乎不是一个选项。
当您将 Entry
的 State
更改为 Added
时,条目的状态及其所有关系的状态将更改为 Added
。所以没有必要单独添加这些关系。
因此,在您的 Create
方法中注释行 UpdateReferences(data, dbEntity);
,一切都会正常进行。
我感觉线路有问题
entity.Entity.Markets = new List<Model.EventManagement.Market>();
放在
之后
dbEntity.State = EntityState.Added;
您可以在实体的构造函数中尝试以下操作吗:
public Exhibition() {
Markets = new List<Model.EventManagement.Market>();
}
然后 :
protected override void UpdateReferences(
Exhibition model,
Model.EventManagement.Exhibition entity)
{
foreach (var market in model.Markets)
{
var marketEntity = Context.Markets.Single(m => m.Id == market.Id);
entity.Markets.Add(marketEntity);
}
}
如果它不能正常工作,可能启用代理是关键。
感谢您为我指明了正确的方向。
这都是关于何时将 State
设置为 Added
。我只需要交换 UpdateReferences
和 State = Added
.
public virtual TDto Create(TDto data)
{
TEntity entity = ToEntity(data);
DbEntityEntry<TEntity> dbEntity = Context.Entry<TEntity>(entity);
// call UpdateReferences first...
UpdateReferences(data, dbEntity);
// ...then set the State to Added
dbEntity.State = EntityState.Added;
Context.SaveChanges();
data = ToModel(dbEntity.Entity);
return data;
}
虽然它现在按预期工作,但它非常令人困惑,因为我认为之后设置状态也会将子状态设置为已添加,但显然不是......¯\_(ツ)_/¯
我的数据在 Exhibitions
和 Markets
之间存在多对多关系。
创建新展览时,应将一些现有市场分配给它。
我创建了一个通用存储库,如下所示:
public virtual TDto Create(TDto data)
{
TEntity entity = ToEntity(data);
DbEntityEntry<TEntity> dbEntity = Context.Entry<TEntity>(entity);
dbEntity.State = EntityState.Added;
UpdateReferences(data, dbEntity);
Context.SaveChanges();
data = ToModel(dbEntity.Entity);
return data;
}
想法是允许每个具体存储库定义它自己的处理方式,以更新它对其他实体的引用。
protected override void UpdateReferences(Exhibition model, DbEntityEntry<Model.EventManagement.Exhibition> entity)
{
entity.Entity.Markets = new List<Model.EventManagement.Market>();
foreach (var market in model.Markets)
{
var marketEntity = Context.Markets.Single(m => m.Id == market.Id);
entity.Entity.Markets.Add(marketEntity);
}
}
出现的问题是,当我创建一个包含已有市场的新展览时,关联的市场会重复。我的上下文使用以下设置:
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
所以,我的问题是如何说服 EF 关联现有市场,而不是创建重复的市场?
我阅读了很多有关将 ID 属性与导航属性一起使用以避免此类问题的文章,但是对于多对多关系,这似乎不是一个选项。
当您将 Entry
的 State
更改为 Added
时,条目的状态及其所有关系的状态将更改为 Added
。所以没有必要单独添加这些关系。
因此,在您的 Create
方法中注释行 UpdateReferences(data, dbEntity);
,一切都会正常进行。
我感觉线路有问题
entity.Entity.Markets = new List<Model.EventManagement.Market>();
放在
之后dbEntity.State = EntityState.Added;
您可以在实体的构造函数中尝试以下操作吗:
public Exhibition() {
Markets = new List<Model.EventManagement.Market>();
}
然后 :
protected override void UpdateReferences(
Exhibition model,
Model.EventManagement.Exhibition entity)
{
foreach (var market in model.Markets)
{
var marketEntity = Context.Markets.Single(m => m.Id == market.Id);
entity.Markets.Add(marketEntity);
}
}
如果它不能正常工作,可能启用代理是关键。
感谢您为我指明了正确的方向。
这都是关于何时将 State
设置为 Added
。我只需要交换 UpdateReferences
和 State = Added
.
public virtual TDto Create(TDto data)
{
TEntity entity = ToEntity(data);
DbEntityEntry<TEntity> dbEntity = Context.Entry<TEntity>(entity);
// call UpdateReferences first...
UpdateReferences(data, dbEntity);
// ...then set the State to Added
dbEntity.State = EntityState.Added;
Context.SaveChanges();
data = ToModel(dbEntity.Entity);
return data;
}
虽然它现在按预期工作,但它非常令人困惑,因为我认为之后设置状态也会将子状态设置为已添加,但显然不是......¯\_(ツ)_/¯