Как Entity Framework ChangeTracker узнает, что свойство изменилось? - PullRequest
0 голосов
/ 27 ноября 2018

Как Entity Framework ChangeTracker узнает, что свойство изменилось?Свойства не имеют расширенного установщика.Я хотел бы знать, как отслеживать эти изменения.

1 Ответ

0 голосов
/ 27 ноября 2018

Если вы используете DbContext и DbSets нормально, вы не будете добавлять элементы в трекер изменений.Прежде чем вы сможете изменить какое-либо свойство объекта, вам сначала нужно его получить.Кроме того, если вы хотите удалить его, сначала вам нужно его извлечь.

Средство отслеживания изменений содержит все извлеченные элементы, по крайней мере, до SaveChanges, но, вероятно, до удаления DbContext, если вы действительно хотите знать, напишите некоторый тестовый код.

ChangeTracker также содержит все добавленные элементы.

Доступ к последовательности выбранных и добавленных элементов в ChangeTracker можно получить с помощью метода Entries или Entries<...>.Возвращаемое значение представляет собой последовательность DbEntityEntries.Каждый DbEntityEntry имеет состояние, указывающее, был ли он добавлен / удален / изменен / неизменен

После того, как вы получили элемент, его состояние остается неизменным.Если вы позвоните Удалить, состояние изменится на Удалено.Если вы добавляете объект в State, если он добавлен.Сложная часть изменена, потому что вы можете изменить элемент без использования 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 содержит исходные значения базы данных, а также текущие значения.Поэтому, когда вы запрашиваете состояние, все, что нужно сделать, это проверить, было ли оно добавлено / удалено / и т.д. Большинство состояний легко, только если оно не изменено, функция, которая выбирает состояние, должна будет проверить все исходные значения с помощьювсе 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
...