实体框架ChangeTracker如何知道属性已更改?该属性没有高级设置器。我想知道如何跟踪这些更改。
答案 0 :(得分:0)
如果您正常使用DbContext和DbSet,则不会将项目添加到更改跟踪器。在更改实体的任何属性之前,您首先必须获取它。另外,如果要删除它,则首先必须获取它。
变更跟踪器将保存所有提取的项目,至少直到SaveChanges为止,但可能直到DbContext被释放为止,如果您真的想知道,请编写一些测试代码。
ChangeTracker还保存所有已添加的项目。
可以使用方法Entries
或Entries<...>
访问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