添加时EF6多对多关系重复条目

时间:2016-07-08 08:31:36

标签: c# .net entity-framework repository-pattern

我的数据在ExhibitionsMarkets之间存在多对多关系。 在创建新展览时,应该为其分配一些现有市场。 我创建了一个通用的存储库,如下所示:

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属性和导航属性来避免这种问题,但是由于多对多的关系,这似乎不是一种选择。

3 个答案:

答案 0 :(得分:1)

当您将State的{​​{1}}更改为Entry时,条目的状态及其所有关系的状态将更改为Added。所以没有必要单独添加这些关系。

请在Added方法中对UpdateReferences(data, dbEntity);行进行评论,一切正常。

答案 1 :(得分:1)

我感觉线路有些问题

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);
    }
}

如果它不能正常工作,可能是启用代理是关键。

答案 2 :(得分:0)

感谢您指点我正确的方向。 这一切都与State设置为Added的时间有关。我只需要交换UpdateReferencesState = 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;
}

虽然它现在按预期工作,但它非常令人困惑,因为我认为之后设置状态也会将子状态设置为添加,但显然不是......¯\ _(ツ)_ /¯