DbContext.ChangeTracker,DbContext.Entry()不一致

时间:2011-11-17 17:04:16

标签: entity-framework-4.1 ef-code-first change-tracking

在调试器下,我遇到DbContext.ChangeTracker.Entry(e)返回State Detached条目的情况。当我在查找DbContext.ChangeTracker.Entries()时枚举ObjectContext的结果和基础e的条目时,我会找到State Unchanged的条目(预期)。

发生了什么事?

以下是一些其他细节:

  • 使用POCO实体。
  • 更改跟踪已开启
  • 代理创建已关闭
  • 延迟加载
  • 第一次保存实体时不会出现问题(例如添加到上下文);将旧实体放入上下文然后尝试对其进行更改时发生。这是一个聚合根,其中包含许多不应更改的“引用”实体
  • 在实体上覆盖了
  • Equals,并实现了IEquatable<T>。该代码由T4生成。
  • 我正在使用声明性配置的通用存储库实现来生成保存规则(例如,是否应添加,附加/修改,附加/不更改实体。它似乎是以正确的顺序执行此操作。例如聚合root是最后添加/附加的,因为首先附加它会导致处于修改状态的其他实体(首先将这些实体添加为未更改状态会阻止它)。

1 个答案:

答案 0 :(得分: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的评论可能表明Equals实施有问题。

如果有人有进一步的解释,他们可以将其编辑到此社区wiki答案中。