实体框架ChangeTracker如何知道属性已更改?

时间:2018-11-27 09:09:00

标签: entity-framework change-tracking

实体框架ChangeTracker如何知道属性已更改?该属性没有高级设置器。我想知道如何跟踪这些更改。

1 个答案:

答案 0 :(得分:0)

如果您正常使用DbContext和DbSet,则不会将项目添加到更改跟踪器。在更改实体的任何属性之前,您首先必须获取它。另外,如果要删除它,则首先必须获取它。

变更跟踪器将保存所有提取的项目,至少直到SaveChanges为止,但可能直到DbContext被释放为止,如果您真的想知道,请编写一些测试代码。

ChangeTracker还保存所有已添加的项目。

可以使用方法EntriesEntries<...>访问ChangeTracker中获取和添加的项目的顺序。返回的值是DbEntityEntries的序列。每个DbEntityEntry都有一个状态,指示是否已添加/删除/修改/不变

获取项目后,其状态为未更改。如果您调用删除,状态将在已删除中更改。如果添加对象,则添加状态。困难的修改是修改,因为您可以在不使用DbSet的情况下修改项目:

// Student moves to different school:
int jfkSchoolId = schoolContext.Schools
    .Where(school => school.Name = "J.F. Kennedy School")
    .Select(school => school.Id)
    .FirstOrDefault();
var student = schoolContext.Students.Where(student.Id == 100).SingleOrDefault();
student.SchoolId = jfkSchoolId;

ChangeTracker如何知道您更改了SchoolId?

幸运的是,DbEntityEntry保留了原始数据库值以及当前值。因此,当您要求状态时,它所要做的就是检查它是否已添加/删除/等。大多数状态很容易,只有将其更改为“ Unchanged”,获取状态的函数才必须使用以下命令检查所有原始值:所有currentValues,使用默认值比较器。如果存在差异,状态将标记为已更改,因此下次无需进行值比较。

您无法撤消此操作:状态更改后,您将无法取消更改:

int originalSchoolId = myStudent.SchoolId;
myStudent.SchoolId = jfxSchoolId;
var state = dbContext.ChangeTracker.Entries<Students>
    .Where(studentEntity => studentEntity.Entity.Id == myStudent.Id)
    .Select(studentEntity => studentEntity.State)
    .SingleOrDefault();
// state equals Changed, because original value was not 0
// student back to original school
myStudent.SchoolId = originalSchoolId;
// ask the state of this student again:    
state = ...
// state is still changed