DetectChanges如何运作?

时间:2014-10-20 08:46:17

标签: c# .net entity-framework

有以下2个实体,具有以下属性:

Parent
    ID
    Children
Child
    ID
    ParentID
    Parent

现在我有以下代码:

db.Configuration.AutoDetectChangesEnabled = false;

var child1=new Child();
parent.Children.Add(child1);
db.ChangeTracker.DetectChanges();
parent.Children.Remove(child1);

var child2=new Child();
child2.Parent=parent;
child2.ParentID=parent.ID;
db.Children.add(child2);

此时,child1和child2完全相同。 Parent和ParentID属性具有相同的值(parent的值)。检查它们的dbContext entry也会显示完全相同的信息,例如OriginalValues对于两者都是空的。

但是,如果我现在调用db.ChangeTracker.DetectChanges,则child1.Parent变为null,而child2.Parent保持其值。 EF如何知道如何做到这一点 - 它在哪里保留所需信息才能产生这种差异?

感谢您提出任何想法

1 个答案:

答案 0 :(得分:1)

一般

  

检测更改的工作原理是检测实体的当前属性值与查询或附加实体时存储在快照中的原始属性值之间的差异。

Entity Framework Automatic Detect Changes

  

确保ObjectStateEntry更改与ObjectStateManager跟踪的所有对象中的更改同步。

ObjectContext.DetectChanges Method

所以在您的示例中,在禁用更改跟踪后,新值将位于原始值之上,直到您决定通过调用context.ChangeTracker.DetectChanges更新模型并同步所有对象(它或多或少地推迟操作)。现在,当您致电DetectChanges时,所有操作(Remove& Add)都会将提交提交给模型,以便以后保存。因此,父项已从child1 parent.Children.Remove(child1)中删除,child2保留其值,因为此处的操作是添加父项(作业)。

您希望禁用更改跟踪的原因是性能:

  

如果您在上下文中跟踪很多实体并且在循环中多次调用这些方法之一,那么通过在循环的持续时间内关闭检测变化,可以显着提高性能。

如果您想了解确切的技术/实施细节,可以浏览源代码:

.NET Framework source code online> DetectChanges