【问题标题】:An entity object cannot be referenced by multiple instances of IEntityChangeTracker EF 6IEntityChangeTracker EF 6 的多个实例无法引用实体对象
【发布时间】:2016-01-16 18:16:31
【问题描述】:

我正在 MVC 5 和 EF 6 中开发应用程序。我正在使用通用方法来更新实体,并使用扩展方法来检测更改的值和属性。当我尝试插入更新的记录时,我得到了错误,

一个实体对象不能被多个 IEntityChangeTracker 实例引用

我的更新代码是:

public void Update(T data)
{
    var originalEntity = db.Set<T>().AsNoTracking().FirstOrDefault(e => e.Id == data.Id);
    var modifiedValues = originalEntity.ModifiedValues<T>(data).ToList();
    for (int i = 0; i < modifiedValues.Count; i++)
    {
       string modifiedField = modifiedValues.ElementAt(i).Key;
       string modifiedValue = modifiedValues.ElementAt(i).Value.ToString();
       PropertyInfo prop = data.GetType().GetProperty(modifiedField, BindingFlags.Public | BindingFlags.Instance);
       string s = prop.PropertyType.GenericTypeArguments.Select(x => x.FullName).SingleOrDefault();
       switch (s)
       {
            case ("System.DateTime"):
            {
                DateTime d = Convert.ToDateTime(modifiedValue);
                prop.SetValue(data, d);
                break;
            }
            case ("System.String"):
            {
                prop.SetValue(data, modifiedValue);
                break;
            }
       }
   }
   Insert(data); // error occurred in this function
   Save();    
}

插入函数的代码是:

public void Insert(T data)
{ db.Set<T>().Add(data); }

在语句db.Set().Add(data);处,出现错误。

我知道当实体已经附加到另一个上下文时会发生这种情况。但在这些函数中,我只使用了一次上下文对象 db,但使用了 AsNoTracking(),因此不应发生此错误。

我希望在this question 中回答并将我的更新函数修改为:

db.Entry(data).State = EntityState.Detached;
Insert(data); // error again occurred in this function
Save(); 

但错误仍然发生。问题是什么?我该如何解决?

我从我的控制器调用更新函数:

private BaseRepository<ABC> g = new BaseRepository<ABC>();
ABC m = new ABC();
m = db.ABCs.Find(id);
m.S107 = "2";
m.D103 = DateTime.Now;
m.S36 = "awais";
g.Update(m);

【问题讨论】:

  • 如何以及在何处检索实体?

标签: c# entity-framework generics


【解决方案1】:

您正在使用m = db.ABCs.Find(id);,它将实体附加到上下文。

换成db.ABCs.AsNoTracking().Where(abc =&gt; abc.Id == id).First();试试

来自DbSet.Find 文档:

... 向商店请求具有给定主实体的实体 键值和该实体(如果找到)附加到上下文 并返回。 ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多