有以下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如何知道如何做到这一点 - 它在哪里保留所需信息才能产生这种差异?
感谢您提出任何想法
答案 0 :(得分:1)
一般
检测更改的工作原理是检测实体的当前属性值与查询或附加实体时存储在快照中的原始属性值之间的差异。
Entity Framework Automatic Detect Changes
和
确保ObjectStateEntry更改与ObjectStateManager跟踪的所有对象中的更改同步。
ObjectContext.DetectChanges Method
所以在您的示例中,在禁用更改跟踪后,新值将位于原始值之上,直到您决定通过调用context.ChangeTracker.DetectChanges
更新模型并同步所有对象(它或多或少地推迟操作)。现在,当您致电DetectChanges
时,所有操作(Remove
& Add
)都会将提交提交给模型,以便以后保存。因此,父项已从child1
parent.Children.Remove(child1)
中删除,child2
保留其值,因为此处的操作是添加父项(作业)。
您希望禁用更改跟踪的原因是性能:
如果您在上下文中跟踪很多实体并且在循环中多次调用这些方法之一,那么通过在循环的持续时间内关闭检测变化,可以显着提高性能。
如果您想了解确切的技术/实施细节,可以浏览源代码: