Entity Framework - Lebenszyklus
Lebenszeit
Die Lebensdauer eines Kontexts beginnt mit der Erstellung der Instanz und endet mit der Entsorgung oder Speicherbereinigung der Instanz.
Die Lebensdauer des Kontexts ist eine sehr wichtige Entscheidung, wenn wir ORMs verwenden.
Der Kontext verhält sich wie ein Entitätscache, dh er enthält Verweise auf alle geladenen Entitäten, deren Speicherverbrauch möglicherweise sehr schnell wächst, und es kann auch zu Speicherverlusten kommen.
In der folgenden Abbildung sehen Sie die obere Ebene des Datenworkflows von der Anwendung zur Datenbank über den Kontext und umgekehrt.
Entity Lifecycle
Der Entitätslebenszyklus beschreibt den Prozess, in dem eine Entität erstellt, hinzugefügt, geändert, gelöscht usw. wird. Entitäten haben während ihrer Lebensdauer viele Zustände. Bevor wir uns ansehen, wie der Entitätsstatus abgerufen wird, werfen wir einen Blick auf den Entitätsstatus. Der Staat ist eine Aufzählung vom TypSystem.Data.EntityState das deklariert die folgenden Werte -
Added: Die Entität wird als hinzugefügt markiert.
Deleted: Die Entität wird als gelöscht markiert.
Modified: Die Entität wurde geändert.
Unchanged: Die Entität wurde nicht geändert.
Detached: Die Entität wird nicht verfolgt.
Statusänderungen im Entity Lifecycle
Manchmal wird der Status von Entitäten automatisch vom Kontext festgelegt, er kann jedoch auch vom Entwickler manuell geändert werden. Obwohl alle Kombinationen von Schaltern von einem Zustand in einen anderen möglich sind, sind einige von ihnen bedeutungslos. Zum Beispiel,Added Entität zum Deleted Zustand oder umgekehrt.
Lassen Sie uns über verschiedene Zustände diskutieren.
Unveränderter Zustand
Wenn eine Entität unverändert ist, ist sie an den Kontext gebunden, wurde jedoch nicht geändert.
Standardmäßig befindet sich eine aus der Datenbank abgerufene Entität in diesem Status.
Wenn eine Entität an den Kontext angehängt wird (mit der Attach-Methode), befindet sie sich ebenfalls im unveränderten Zustand.
Der Kontext kann keine Änderungen an Objekten verfolgen, auf die er nicht verweist. Wenn sie angehängt sind, wird davon ausgegangen, dass sie unverändert sind.
Freistehender Zustand
Getrennt ist der Standardstatus einer neu erstellten Entität, da der Kontext die Erstellung eines Objekts in Ihrem Code nicht verfolgen kann.
Dies gilt auch dann, wenn Sie die Entität innerhalb eines using-Blocks des Kontexts instanziieren.
Getrennt ist sogar der Status von Entitäten, die aus der Datenbank abgerufen werden, wenn die Verfolgung deaktiviert ist.
Wenn eine Entität getrennt wird, ist sie nicht an den Kontext gebunden, sodass ihr Status nicht verfolgt wird.
Es kann entsorgt, geändert, in Kombination mit anderen Klassen verwendet oder auf andere Weise verwendet werden, die Sie möglicherweise benötigen.
Da es keinen Kontext gibt, der es verfolgt, hat es für Entity Framework keine Bedeutung.
Status hinzugefügt
Wenn sich eine Entität im Status Hinzugefügt befindet, haben Sie nur wenige Optionen. Tatsächlich können Sie es nur vom Kontext trennen.
Selbst wenn Sie eine Eigenschaft ändern, bleibt der Status natürlich Hinzugefügt, da es keinen Sinn macht, ihn in Geändert, Unverändert oder Gelöscht zu verschieben.
Es ist eine neue Entität und hat keine Korrespondenz mit einer Zeile in der Datenbank.
Dies ist eine Grundvoraussetzung, um sich in einem dieser Staaten zu befinden (diese Regel wird jedoch vom Kontext nicht durchgesetzt).
Geänderter Zustand
Wenn eine Entität geändert wird, bedeutet dies, dass sie sich im unveränderten Zustand befindet und dann eine Eigenschaft geändert wurde.
Nachdem eine Entität in den Status "Geändert" eingetreten ist, kann sie in den Status "Getrennt" oder "Gelöscht" versetzt werden. Sie kann jedoch auch dann nicht in den Status "Unverändert" zurückgesetzt werden, wenn Sie die ursprünglichen Werte manuell wiederherstellen.
Es kann nicht einmal in "Hinzugefügt" geändert werden, es sei denn, Sie trennen die Entität und fügen sie dem Kontext hinzu, da eine Zeile mit dieser ID bereits in der Datenbank vorhanden ist und Sie eine Laufzeitausnahme erhalten, wenn Sie sie beibehalten.
Gelöschter Zustand
Eine Entität wechselt in den Status Gelöscht, weil sie unverändert oder geändert wurde und dann die DeleteObject-Methode verwendet wurde.
Dies ist der restriktivste Zustand, da es sinnlos ist, von diesem Zustand zu einem anderen Wert als "Abgelöst" zu wechseln.
Das usingAnweisung, wenn alle Ressourcen, die der Kontext steuert, am Ende des Blocks entsorgt werden sollen. Wenn Sie die verwendenusing Anweisung, dann erstellt der Compiler automatisch einen try / finally-Block und ruft dispose im finally-Block auf.
using (var context = new UniContext()) {
var student = new Student {
LastName = "Khan",
FirstMidName = "Ali",
EnrollmentDate = DateTime.Parse("2005-09-01")
};
context.Students.Add(student);
context.SaveChanges();
}
Beachten Sie bei der Arbeit mit einem langfristigen Kontext Folgendes:
Wenn Sie mehr Objekte und ihre Referenzen in den Speicher laden, kann sich der Speicherverbrauch des Kontexts schnell erhöhen. Dies kann zu Leistungsproblemen führen.
Denken Sie daran, den Kontext zu entsorgen, wenn er nicht mehr benötigt wird.
Wenn eine Ausnahme dazu führt, dass sich der Kontext in einem nicht wiederherstellbaren Zustand befindet, wird die gesamte Anwendung möglicherweise beendet.
Die Wahrscheinlichkeit, dass Probleme im Zusammenhang mit der Parallelität auftreten, steigt mit zunehmender Zeitspanne zwischen der Abfrage und Aktualisierung der Daten.
Verwenden Sie bei der Arbeit mit Webanwendungen eine Kontextinstanz pro Anforderung.
Verwenden Sie bei der Arbeit mit Windows Presentation Foundation (WPF) oder Windows Forms eine Kontextinstanz pro Formular. Auf diese Weise können Sie die vom Kontext bereitgestellte Änderungsverfolgungsfunktion verwenden.
Faustregeln
Web Applications
Es ist mittlerweile eine gängige und bewährte Methode, dass für Webanwendungen der Kontext pro Anforderung verwendet wird.
In Webanwendungen werden Anfragen bearbeitet, die sehr kurz sind, aber alle Servertransaktionen enthalten. Daher ist dies die richtige Dauer für den Kontext.
Desktop Applications
Für Desktop-Anwendungen wie Win Forms / WPF usw. wird der Kontext pro Formular / Dialog / Seite verwendet.
Da wir den Kontext nicht als Singleton für unsere Anwendung haben möchten, werden wir ihn entsorgen, wenn wir von einem Formular in ein anderes wechseln.
Auf diese Weise erhalten wir viele Fähigkeiten des Kontexts und leiden nicht unter den Auswirkungen lang laufender Kontexte.