2011-11-17 81 views
1

在调试器下,我有一个情况,其中DbContext.ChangeTracker.Entry(e)返回StateDetached的条目。当我列举DbContext.ChangeTracker.Entries()的结果和ObjectContext查找e的条目时,我找到StateUnchanged(预期)的条目。DbContext.ChangeTracker,DbContext.Entry()不一致

这是怎么回事?

这里有一些额外的细节:

  • 使用POCO实体。
  • 变化跟踪是上
  • 代理创建熄灭
  • 迟缓装载是关闭
  • 节省了第一时间(例如增加上下文)的实体时,不会发生问题;在将旧实体置于上下文中然后尝试对其进行更改时发生。这是具有许多不应该改变的“参考”实体的聚合根
  • Equals在实体上被覆盖,IEquatable<T>被实施。该代码由T4生成。
  • 我正在使用一个通用的存储库实现,它声明性地配置为生成保存规则(例如,是否应该添加实体,附加/修改,附加/不变),它似乎是以正确的顺序执行此操作,例如聚合根被添加/附最后,因为附接它首先使在其他实体在修改状态(添加那些首先作为不变防止这一点)。
+1

你叫'DetectChanges'吗? – SLaks

+0

@SLaks - 不,这可能是我必须做的事情吗? – Kit

+0

提供有关您的情况的更多细节(您做了什么来获得这种不一致)。还要确保e和'ChangeTracker'中的实例相同,并且你没有重写实体上的'Equals'方法。 –

回答

0

(回答一个问题编辑。转换为一个社区维基答案。参见Question with no answers, but issue solved in the comments (or extended in chat)

该OP写道:

我已经“解决”了这个问题,但我仍然想知道发生了什么,因为我的解决方案没有做任何事情来解决根本原因。我的“解决方案”寻找变化跟踪器中的实体(我也通过context.Entry()context.Set().Local查看 - 当我使用此代码(我将其作为循环代替LINQ,因此可以设置断点)执行时,它可以工作:

private DbEntityEntry GetChangeTrackedEntry(IEntity mine, Type type) 
    { 
     foreach (var en in context.ChangeTracker.Entries()) 
     { 
      if (en.Entity.GetType() != type) 
       continue; 
      if (((IEntity)en.Entity).Id != mine.Id) 
       continue; 
      return en; 
     } 

     return null; 
    } 

当我尝试通过直接使用矿查找一个实体(通过变更跟踪器,所述一组,等等),这是当我结束了一个分离的情况下

予。想到也许有EF使用ReferenceEquals的情况,但是@ Ladislav的评论可能表明有错误实现。

如果有人有进一步的解释,他们可以编辑到这个社区维基答案。