Identitätsauflösung, Zustandsverwaltung und Änderungsnachverfolgung (Entity Framework)
Der ObjectContext stellt einen Container für Objekte im Arbeitsspeicher dar. Der Objektkontext verwaltet mit der Hilfe von anderen Klassen und Schnittstellen die Identität eines Objekts, dessen Zustand, die ursprünglichen und aktuelle Werte der Eigenschaften des Objekts und verfolgt die an jedem Objekt im Cache vorgenommenen Änderungen. Informationen zum Anfügen von Objekten an den Objektkontext finden Sie unter Anfügen und Trennen von Objekten (Entity Framework). In diesem Thema wird erläutert, wie der Objektkontext Änderungsnachverfolgung, Identitätsauflösung und Zustandsverwaltung verwaltet.
Änderungsnachverfolgung
Änderungsnachverfolgungsinformationen für das Objektdiagramm werden in ObjectStateEntry-Objekten gespeichert, die für jedes angefügte Objekt vom ObjectContext erstellt werden. ObjectStateEntry-Objekte speichern die folgenden Informationen für die Entitäten:
Den EntityKey, der die Identität einer Entität bestimmt.
Den EntityState für das Objekt.
Informationen zu verknüpften Objekten
Der Name der Entitätenmenge
CurrentValues und OriginalValues der Entitätseigenschaften (Objekte in einem Added-Zustand verfügen nicht über ursprüngliche Werte)
Die Namen der geänderten Entitätseigenschaften.
Um zu ermitteln, ob der Wert einer Eigenschaft zwischen den Aufrufen von SaveChanges geändert wurde, fragen Sie die Auflistung der geänderten Eigenschaftennamen ab, die von der GetModifiedProperties-Methode zurückgegeben wird.
Hinweis: |
---|
Wenn Sie mit POCO-Entitäten ohne Änderungsnachverfolgungsproxys arbeiten, müssen Sie DetectChanges vor dem Aufruf von GetModifiedProperties aufrufen. |
Wenn eine Entität vom Objektkontext getrennt wird, wird das zugehörige ObjectStateEntry-Objekt aus dem Objektkontext entfernt.
Die ObjectStateEntry-Objekte werden vom ObjectStateManager verwaltet. Pro Objektkontext ist eine Instanz von ObjectStateManager vorhanden. Um das ObjectStateEntry-Objekt für die angegebene Entität abzurufen, verwenden Sie eine der folgenden Methoden für ObjectStateManager: TryGetObjectStateEntry, GetObjectStateEntry oder GetObjectStateEntries.
Der Objektkontext wird über die Änderungen an Eigenschaften von in Entity Framework generierten Entitäten und POCO-Änderungsnachverfolgungsproxyobjekten benachrichtigt, sobald diese auftreten, und aktualisiert den Zustand von Objekten und die Werte der Eigenschaften im ObjectStateEntry. Das Berichtsmodell für Änderungen ermöglicht es, eine ausstehende Änderung an einer Eigenschaft zu melden, die Eigenschaft festzulegen und anschließend mithilfe der IEntityChangeTracker-Schnittstelle zu melden, dass die Änderung abgeschlossen ist. ObjectStateEntry verwaltet POCO-Entitäten ohne Änderungsnachverfolgungsproxyobjekte und komplexe Typobjekte unterschiedlich. Weitere Informationen finden Sie unter Verfolgen von Änderungen in POCO-Entitäten (Entity Framework).
Der Objektkontext verwendet die Informationen in den ObjectStateEntry-Objekten, um Daten in der Datenquelle beizubehalten. Weitere Informationen finden Sie unter Speichern von Änderungen und Verwalten von Parallelität (Entity Framework) und Gewusst wie: Ausführen von Geschäftslogik beim Speichern von Änderungen (Entity Framework).
Identitätsauflösung und Zusammenführungsoptionen
Entity Framework behält nur eine Instanz eines Objekts mit einem bestimmten Entitätsschlüssel im Cache. Die EntityKey-Objekte sind unveränderliche Objekte, die die Identität des Objekts darstellen. Entitätsschlüssel werden verwendet, um die Identitätsauflösung im Objektkontext auszuführen. Weitere Informationen finden Sie unter Arbeiten mit Entitätsschlüsseln (Entity Framework). Wenn eine Entität mit der gleichen Identität bereits verfolgt wird, werden die Daten, die von der Datenquelle kommen, entsprechend der MergeOption-Einstellung der Abfrage mit den Daten zusammengeführt, die bereits im Zustands-Manager enthalten sind.
In der folgenden Tabelle finden Sie die möglichen Zusammenführungsoptionen:
Element | Beschreibung |
---|---|
Objekte, die nicht im Objektkontext vorhanden sind, werden an den Kontext angefügt. Wenn sich ein Objekt bereits im Kontext befindet, werden die aktuellen und ursprünglichen Werte der Objekteigenschaften im Eintrag nicht mit Datenquellenwerten überschrieben. Der Zustand des Objekteintrags und der Objekteigenschaften des Eintrags werden nicht geändert. AppendOnly ist die Standardzusammenführungsoption. |
|
Objekte, die nicht im Objektkontext vorhanden sind, werden an den Kontext angefügt. Wenn sich ein Objekt bereits im Kontext befindet, werden die aktuellen und ursprünglichen Werte der Objekteigenschaften im Eintrag mit Datenquellenwerten überschrieben. Der Zustand des Objekteintrags wird auf Unchanged festgelegt. Dabei werden keine Eigenschaften als geändert markiert. |
|
Objekte, die nicht im Objektkontext vorhanden sind, werden an den Kontext angefügt. Wenn der Zustand der Entität Unchanged ist, werden die aktuellen und ursprünglichen Werte des Eintrags mit Datenquellenwerten überschrieben. Der Zustand der Entität bleibt Unchanged, und es werden keine Eigenschaften als geändert markiert. Wenn der Zustand der Entität Modified ist, werden die aktuellen Werte geänderter Eigenschaften nicht mit Datenquellenwerten überschrieben. Die ursprünglichen Werte ungeänderter Eigenschaften werden mit den Werten der Datenquelle überschrieben. In .NET Framework Version 4 vergleicht Entity Framework die aktuellen Werte ungeänderter Eigenschaften mit den Werten, die von der Datenquelle zurückgegeben wurden. Wenn die Werte nicht identisch sind, wird die Eigenschaft als geändert markiert. In .NET Framework Version 3.5 SP1 markiert Entity Framework die Eigenschaft selbst dann nicht als geändert, wenn der Wert in der Datenquelle abweicht. Nur geänderte Eigenschaften werden beim Aufrufen von SaveChanges in der Datenquelle beibehalten. Um das Verhalten von 3.5 SP1 beizubehalten, legen Sie UseLegacyPreserveChangesBehavior auf true fest. Die Option PreserveChanges kann verwendet werden, um Ausnahmen bzgl. vollständiger Parallelität aufzulösen und gleichzeitig Änderungen im lokalen Kontext beizubehalten. Weitere Informationen finden Sie unter Speichern von Änderungen und Verwalten von Parallelität (Entity Framework). |
|
Objekte werden im Detached-Zustand beibehalten und nicht im ObjectStateManager nachverfolgt. Von Entity Framework generierte Entitäten und POCO-Entitäten mit Proxys verwalten jedoch einen Verweis auf den Objektkontext, um das Laden von verknüpften Objekten zu erleichtern. |
Entitätszustand
Der Objektkontext muss den Zustand eines Objekts kennen, um Änderungen in der Datenquelle speichern zu können. ObjectStateEntry-Objekte speichern EntityState-Informationen. Die SaveChanges-Methoden von ObjectContext verarbeiten Entitäten, die an den Kontext angefügt werden, und aktualisieren die Datenquelle abhängig vom EntityState-Zustand der einzelnen Objekte. Weitere Informationen finden Sie unter Erstellen, Hinzufügen, Ändern und Löschen von Objekten (Entity Framework). In der folgenden Tabelle werden die möglichen Zustände eines Objekts aufgelistet:
Element | Beschreibung |
---|---|
Added |
Das Objekt ist neu, es wurde dem Objektkontext hinzugefügt, und die SaveChanges-Methode wurde nicht aufgerufen. Wenn die Änderungen gespeichert wurden, ändert sich der Objektzustand zu Unchanged. Objekte im Zustand Added verfügen im ObjectStateEntry nicht über ursprüngliche Werte. |
Das Objekt wurde aus dem Objektkontext gelöscht. Nachdem die Änderungen gespeichert wurden, ändert sich der Objektzustand zu Detached. |
|
Detached |
Das Objekt ist vorhanden, wird jedoch nicht nachverfolgt. Eine Entität befindet sich unmittelbar nach der Erstellung und bevor sie dem Objektkontext hinzugefügt wurde in diesem Zustand. Eine Entität befindet sich auch in diesem Zustand, nachdem sie durch einen Aufruf der Detach-Methode aus dem Kontext entfernt wurde oder wenn sie mithilfe einer NoTrackingMergeOption geladen wurde. Keine Instanz von ObjectStateEntry wurde Objekten im Zustand Detached zugeordnet. |
Modified |
Eine der skalaren Eigenschaften für das Objekt wurde geändert, und die SaveChanges-Methode wurde nicht aufgerufen. In POCO-Entitäten ohne Änderungsnachverfolgungsproxys ändert sich der Zustand der geänderten Eigenschaften zu Modified, wenn die DetectChanges-Methode aufgerufen wird. Wenn die Änderungen gespeichert wurden, ändert sich der Objektzustand zu Unchanged. |
Unchanged |
Das Objekt wurde nicht geändert, seit es an den Kontext angefügt wurde oder die SaveChanges-Methode zuletzt aufgerufen wurde. |
Der Zustand von Objekten in einem Objektkontext wird vom ObjectStateManager verwaltet. Um den Zustand eines Objekts zu ermitteln, rufen Sie eine der folgenden ObjectStateManager-Methoden auf: TryGetObjectStateEntry, GetObjectStateEntry oder GetObjectStateEntries. Die State-Eigenschaft des ObjectStateEntry-Objekts definiert den Objektzustand.