Entity Framework - отслеживание изменений

Entity Framework предоставляет возможность отслеживать изменения, внесенные в сущности и их отношения, поэтому правильные обновления производятся в базе данных при вызове метода контекста SaveChanges. Это ключевая особенность Entity Framework.

  • Отслеживание изменений отслеживает изменения при добавлении новых записей в коллекцию сущностей, изменении или удалении существующих сущностей.

  • Затем все изменения сохраняются на уровне DbContext.

  • Эти изменения трека теряются, если они не сохраняются до уничтожения объекта DbContext.

  • Класс DbChangeTracker предоставляет вам всю информацию о текущих объектах, отслеживаемых контекстом.

  • Чтобы отслеживать любую сущность по контексту, она должна иметь свойство первичного ключа.

В Entity Framework отслеживание изменений включено по умолчанию. Вы также можете отключить отслеживание изменений, установив для свойства AutoDetectChangesEnabled DbContext значение false. Если для этого свойства установлено значение true, Entity Framework поддерживает состояние сущностей.

using (var context = new UniContextEntities()) {
   context.Configuration.AutoDetectChangesEnabled = true;
}

Давайте посмотрим на следующий пример, в котором студенты и их зачисления извлекаются из базы данных.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Configuration.AutoDetectChangesEnabled = true;
         Console.WriteLine("Retrieve Student");

         var student = (from s in context.Students where s.FirstMidName == 
            "Ali" select s).FirstOrDefault<Student>();

         string name = student.FirstMidName + " " + student.LastName;
         Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);
         Console.WriteLine();
         Console.WriteLine("Retrieve all related enrollments");

         foreach (var enrollment in student.Enrollments) {
            Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
               enrollment.EnrollmentID, enrollment.CourseID);
         }

         Console.WriteLine();

         Console.WriteLine("Context tracking changes of {0} entity.", 
            context.ChangeTracker.Entries().Count());

         var entries = context.ChangeTracker.Entries();

         foreach (var entry in entries) {
            Console.WriteLine("Entity Name: {0}", entry.Entity.GetType().Name);
            Console.WriteLine("Status: {0}", entry.State);
         }

         Console.ReadKey();
      }
   }
}

Когда приведенный выше пример скомпилирован и выполнен, вы получите следующий результат.

Retrieve Student 
ID: 1, Name: Ali Alexander
Retrieve all related enrollments
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041
Context tracking changes of 4 entity.
Entity Name: Student
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged
Entity Name: Enrollment
Status: Unchanged

Вы можете видеть, что все данные извлекаются только из базы данных, поэтому статус не меняется для всех сущностей.

Давайте теперь посмотрим на другой простой пример, в котором мы добавим еще одну регистрацию и удалим одного студента из базы данных. Ниже приведен код, в котором добавляется новая регистрация и удаляется один студент.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         context.Configuration.AutoDetectChangesEnabled = true;

         Enrollment enr = new Enrollment() { 
            StudentID = 1, CourseID = 3141 
         };

         Console.WriteLine("Adding New Enrollment");
         context.Enrollments.Add(enr);
         Console.WriteLine("Delete Student");

         var student = (from s in context.Students where s.ID == 
            23 select s).SingleOrDefault<Student>();

         context.Students.Remove(student);
         Console.WriteLine("");

         Console.WriteLine("Context tracking changes of {0} entity.", 
            context.ChangeTracker.Entries().Count());
         var entries = context.ChangeTracker.Entries();

         foreach (var entry in entries) {
            Console.WriteLine("Entity Name: {0}", entry.Entity.GetType().Name);
            Console.WriteLine("Status: {0}", entry.State);
         }

         Console.ReadKey();
      }
   }
}

Когда приведенный выше пример скомпилирован и выполнен, вы получите следующий вывод.

Adding New Enrollment
Delete Student
Context tracking changes of 2 entity.
Entity Name: Enrollment
Status: Added
Entity Name: Student
Status: Deleted

Теперь вы можете видеть, что статус объекта регистрации установлен на добавленный, а статус объекта студент удален, потому что была добавлена ​​новая регистрация и один студент удален из базы данных.

Мы рекомендуем вам выполнить приведенный выше пример поэтапно для лучшего понимания.