Entity Framework - Änderungen verfolgen

Entity Framework bietet die Möglichkeit, die an Entitäten und ihren Beziehungen vorgenommenen Änderungen zu verfolgen, sodass beim Aufrufen der Kontextmethode SaveChanges die richtigen Aktualisierungen in der Datenbank vorgenommen werden. Dies ist eine wichtige Funktion des Entity Framework.

  • Die Änderungsverfolgung verfolgt Änderungen, während der Entitätssammlung neue Datensätze hinzugefügt und vorhandene Entitäten geändert oder entfernt werden.

  • Dann werden alle Änderungen von der DbContext-Ebene beibehalten.

  • Diese Spuränderungen gehen verloren, wenn sie nicht gespeichert werden, bevor das DbContext-Objekt zerstört wird.

  • Die DbChangeTracker-Klasse bietet Ihnen alle Informationen zu aktuellen Entitäten, die vom Kontext verfolgt werden.

  • Um eine Entität anhand des Kontexts zu verfolgen, muss sie über die Primärschlüsseleigenschaft verfügen.

In Entity Framework ist die Änderungsverfolgung standardmäßig aktiviert. Sie können die Änderungsverfolgung auch deaktivieren, indem Sie die AutoDetectChangesEnabled-Eigenschaft von DbContext auf false setzen. Wenn diese Eigenschaft auf true festgelegt ist, behält das Entity Framework den Status von Entitäten bei.

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

Schauen wir uns das folgende Beispiel an, in dem die Schüler und ihre Einschreibungen aus der Datenbank abgerufen werden.

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();
      }
   }
}

Wenn das obige Beispiel kompiliert und ausgeführt wird, erhalten Sie die folgende Ausgabe.

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

Sie können sehen, dass alle Daten nur aus der Datenbank abgerufen werden, weshalb der Status für alle Entitäten unverändert bleibt.

Schauen wir uns nun ein weiteres einfaches Beispiel an, in dem wir eine weitere Einschreibung hinzufügen und einen Schüler aus der Datenbank löschen. Im Folgenden finden Sie den Code, in dem eine neue Registrierung hinzugefügt und ein Schüler gelöscht wird.

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();
      }
   }
}

Wenn das obige Beispiel kompiliert und ausgeführt wird, erhalten Sie die folgende Ausgabe.

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

Sie können jetzt sehen, dass der Status der Registrierungsentität auf "Hinzufügen" gesetzt und der Status der Studentenentität gelöscht wird, da eine neue Registrierung hinzugefügt wurde und ein Student aus der Datenbank entfernt wurde.

Wir empfehlen, dass Sie das obige Beispiel zum besseren Verständnis Schritt für Schritt ausführen.