【问题标题】:Replace multiple instances of an object with single instance in a graph of objects用对象图中的单个实例替换对象的多个实例
【发布时间】:2014-03-01 15:00:55
【问题描述】:

[更新]

我正在使用EF code first,在我的情况下,我必须断开我的POCOs 与DbContext 的连接,当我想将更改保存回DB 时,附加断开连接的POCOs(通过附加根对象)到DbContext,但在我想要保存的对象图中,可能是具有相同键的实体的多个实例。 例如:

Order1
|
OrderLine1-->Product1 //instance1 of product1
|
OrderLine2-->Product1 //instance2 of product1

所以我得到以下错误:

ObjectStateManager 中已存在具有相同键的对象。 ObjectStateManager 无法跟踪具有相同的多个对象 键。

所以我想编写一种方法,在我的ApplyChange() 方法中用一个实例查找和替换对象的重复实例:

public void ApplyChanges<TEntity>(TEntity root) where TEntity : BaseEntity
{
        _dbContext.Set<TEntity>().Add(root);
        foreach (var entry in _dbContext.ChangeTracker
        .Entries<BaseEntity>())
        {
            if (FoundAnEntityWithSameKeyInDbContext<TEntity>(entry))
                UniqeSimilarEntities(entry);
            else
            {
              ....  
            }
        }
}

我写了这段代码:

private bool FoundAnEntityWithSameKeyInDbContext<TEntity>(DbEntityEntry<BaseEntity> entry) where TEntity : BaseEntity
{
        var tmp = _dbContext.ChangeTracker.Entries<BaseEntity>().Count(t => t.Entity.Id == entry.Entity.Id && t.Entity.Id != 0 && t.Entity.GetType() == entry.Entity.GetType());
        if (tmp > 1)
            return true;
        return false;
    }
private void UniqeSimilarEntities(DbEntityEntry<BaseEntity> entry)
{
        var similarEntities = _dbContext.ChangeTracker.Entries<BaseEntity>()
        .Where(
            t =>
                t.Entity.Id == entry.Entity.Id && t.Entity.Id != 0 &&
                t.Entity.GetType() == entry.Entity.GetType()).ToList();

        for (int i = 1; i < similarEntities.Count; i++)
        {
          _dbContext.Entry(similarEntities[i]).CurrentValues.SetValues(similarEntities[0]);
            similarEntities[i].State= EntityState.Unchanged;
        }
}

我的所有实体都继承自 BaseEntity 类:

public class BaseEntity
{
  public int Id {get; set;}
  public States State { get; set; }
  public bool MustDelete {get; set;} 
  ... 
}

但是当控制到达UniqeSimilarEntities方法行_dbContext.Entry(similarEntities[i]).CurrentValues.SetValues...我得到这个错误:

实体类型 DbEntityEntry`1 不是当前上下文模型的一部分。

有没有办法用我的根对象中的一个实例替换重复的实体?

【问题讨论】:

    标签: c# entity-framework ef-code-first dbcontext


    【解决方案1】:

    恕我直言,您应该在附加之前取消重复。在伪代码中:

    List<Product> lp = new List<Product>();
    foreach (var line in Order.Lines) {
        Product p = lp.Where(x => x.Id == line.Product.Id).FirstOrDefault();
        if ( p == null ) {
            lp.Add(p);
        } else {
           line.Product = p;
        }
    }
    

    【讨论】:

    • Order,OrderLine,Product 是一个例子,我想在我的根对象中取消重复对象(它是从 BaseEntity 继承的对象)。我更新了帖子。
    猜你喜欢
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多