DetectChanges如何运作?

wez*_*ten 5 .net c# entity-framework

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

Parent
    ID
    Children
Child
    ID
    ParentID
    Parent
Run Code Online (Sandbox Code Playgroud)

现在我有以下代码:

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);
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢你的任何想法

t3c*_*b0t 4

一般来说

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

实体框架自动检测更改

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

ObjectContext.DetectChanges 方法

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

您想要禁用更改跟踪的原因是性能:

如果您正在跟踪上下文中的大量实体,并且在循环中多次调用其中一种方法,那么通过在循环期间关闭更改检测,您可能会获得显着的性能改进。

如果您想了解确切的技术/实现细节,您可以深入研究源代码:

.NET Framework 在线源代码> DetectChanges

  • DetectChanges 如何知道执行了哪些操作?我看不出这如何回答这个问题。 (5认同)