Objektzustände und Änderungsverfolgung (LINQ to SQL)

Aktualisiert: November 2007

LINQ to SQL-Objekte weisen stets einen Zustand auf. Wenn LINQ to SQL z. B. ein neues Objekt erstellt, befindet sich dieses im Unchanged-Zustand. Ein neues, selbst erstelltes Objekt ist dem DataContext nicht bekannt und befindet sich im Untracked-Zustand. Nach der erfolgreichen Ausführung von SubmitChanges befinden sich alle LINQ to SQL bekannten Objekte im Unchanged-Zustand. (Die einzige Ausnahme besteht in Objekten, die erfolgreich aus der Datenbank gelöscht wurden und sich im Deleted-Zustand befinden, weshalb sie für die DataContext-Instanz nicht nutzbar sind.)

Objektzustände

In der folgenden Tabelle werden die möglichen Zustände für LINQ to SQL-Objekte aufgelistet.

Zustand

Beschreibung

Untracked

Ein Objekt, das nicht von LINQ to SQL verfolgt wird. Die Beispiele umfassen:

  • Ein Objekt, das nicht vom aktuellen DataContext abgefragt wird (z. B. ein neu erstelltes Objekt).

  • Ein durch Deserialisierung erstelltes Objekt

  • Ein Objekt, das durch einen anderen DataContext abgefragt wird.

Unchanged

Ein Objekt, das mit dem aktuellen DataContext abgefragt wurde und von dem nicht bekannt ist, ob es seit der Erstellung verändert wurde.

PossiblyModified

Ein Objekt, das an einen DataContextangehängt wurde. Weitere Informationen finden Sie unter Datenabruf und CUD-Operationen in N-Tier-Anwendungen (LINQ to SQL).

ToBeInserted

Ein Objekt, das nicht vom aktuellen DataContext abgerufen wurde. Dies führt zu einem Datenbank-INSERT während SubmitChanges.

ToBeUpdated

Ein Objekt, von dem bekannt ist, dass es seit dem Abruf verändert wurde. Dies führt zu einem Datenbank-UPDATE während SubmitChanges.

ToBeDeleted

Ein zum Löschen markiertes Objekt, das zu einem Datenbank-DELETE während SubmitChanges führt.

Deleted

Ein Objekt, das in der Datenbank gelöscht wurde. Dieser Zustand ist endgültig und ermöglicht keine zusätzlichen Übergänge.

Einfügen von Objekten

Sie können Inserts mithilfe von InsertOnSubmit explizit anfordern. Alternativ dazu kann LINQ to SQL zu Inserts führen, indem Objekte ermittelt werden, die mit einem der bekannten, zu aktualisierenden Objekte verbunden sind. Wenn Sie beispielsweise ein Untracked-Objekt einem EntitySet<TEntity> hinzufügen oder einen EntityRef<TEntity> für ein Untracked-Objekt festlegen, ist das Untracked-Objekt über verfolgte Objekte im Diagramm erreichbar. Während der Verarbeitung von SubmitChanges, durchläuft LINQ to SQL die verfolgten Objekte und ermittelt alle erreichbaren vorhandenen Objekte, die nicht verfolgt werden. Solche Objekte sind Kandidaten für das Einfügen in die Datenbank.

Bei Klassen in einer Vererbungshierarchie legt InsertOnSubmit(o) auch den Wert des als Diskriminator bezeichneten Members fest, um den Typ des o-Objekts anzupassen. Entspricht ein Typ dem standardmäßigen Diskriminatorwert, wird durch diese Aktion der Diskriminatorwert mit dem Standardwert überschrieben. Weitere Informationen finden Sie unter Vererbungsunterstützung (LINQ to SQL).

Wichtiger Hinweis:

Ein der Table hinzugefügtes Objekt befindet sich nicht im Identitäts-Cache. Der Identitäts-Cache enthält nur die Elemente, die aus der Datenbank abgerufen werden. Nach einem Aufruf von InsertOnSubmit erscheint die hinzugefügte Entität erst dann in den Abfragen für die Datenbank, wenn SubmitChanges erfolgreich abgeschlossen wurde.

Löschen von Objekten

Sie können ein nachverfolgtes Objekt o zur Löschung markieren, indem Sie DeleteOnSubmit(o) für die entsprechende Table<TEntity> aufrufen. LINQ to SQL berücksichtigt das Entfernen eines Objekts aus einem EntitySet<TEntity> als Aktualisierungsvorgang. Hierbei wird der entsprechende Fremdschlüssel auf NULL gesetzt. Das Ziel der Operation (o) wird nicht aus seiner Tabelle gelöscht. cust.Orders.DeleteOnSubmit(ord) weist beispielsweise auf eine Aktualisierung hin, wenn die Beziehung zwischen cust und ord durch Festlegen des Fremdschlüssels ord.CustomerID auf NULL getrennt wurde. Hierbei wird die entsprechende Zeile für ord nicht gelöscht.

LINQ to SQL führt die folgende Verarbeitung durch, wenn ein Objekt (DeleteOnSubmit) aus seiner Tabelle gelöscht wird:

  • Wenn SubmitChanges aufgerufen wird, wird eine DELETE-Operation für dieses Objekt ausgeführt.

  • Die Löschung wird unabhängig davon, ob diese geladen sind, nicht an verwandte Objekte weitergeleitet. Verwandte Objekte werden vor allem nicht geladen, um die Beziehungseigenschaft zu aktualisieren.

  • Nach erfolgreicher Ausführung von SubmitChanges werden die Objekte auf den Deleted-Zustand festgelegt. Daher können Sie das Objekt oder seine id nicht in diesem DataContext verwenden. Der interne Cache einer DataContext-Instanz eliminiert keine Objekte, die abgerufen oder neu hinzugefügt wurden, auch wenn diese in der Datenbank gelöscht wurden.

Sie können DeleteOnSubmit nur für ein Objekt aufrufen, das vom DataContext verfolgt wird. Bei einem Untracked-Objekt müssen Sie Attach vor DeleteOnSubmit aufrufen. Der Aufruf von DeleteOnSubmit für ein Untracked-Objekt löst eine Ausnahme aus.

Hinweis:

Das Entfernen eines Objekts aus einer Tabelle weist LINQ to SQL an, einen entsprechenden SQL DELETE-Befehl zum Zeitpunkt von SubmitChanges zu erstellen. Diese Aktion entfernt das Objekt nicht aus dem Cache und gibt das Löschen auch nicht an verwandte Objekte weiter.

Um die id eines gelöschten Objekts freizugeben, verwenden Sie eine neue DataContext-Instanz. Zur Bereinigung verwandter Objekte können Sie das Feature kaskadierte Löschung der Datenbank verwenden oder die verwandten Objekte manuell löschen.

Die verwandten Objekte müssen in keiner besonderen Reihenfolge gelöscht werden (im Gegensatz zur Datenbank).

Aktualisieren von Objekten

Sie können Updates durch Überwachen der Änderungsmitteilungen erkennen. Benachrichtigungen werden durch das PropertyChanging-Ereignis in Eigenschaften-Settern bereitgestellt. Wird LINQ to SQL über die erste Änderung an einem Objekt benachrichtigt, wird eine Kopie dieses Objekts erstellt, und das Objekt gilt als Kandidat zur Erzeugung einer Update-Anweisung.

Bei Objekten, die INotifyPropertyChanging nicht implementieren, behält LINQ to SQL eine Kopie der Werte bei, die die Objekte bei der ersten Materialisierung aufwiesen. Wenn Sie SubmitChanges aufrufen, vergleicht LINQ to SQL die aktuellen und ursprünglichen Werte, um zu entscheiden, ob das Objekt geändert wurde.

Bei Aktualisierungen von Beziehungen gilt der Verweis vom unter- zum übergeordneten Element (der Verweis, der dem Fremdschlüssel entspricht) als Autorität. Der Verweis in die umgekehrte Richtung (d. h. vom übergeordneten zum untergeordneten Element) ist optional. Beziehungsklassen (EntitySet<TEntity> und EntityRef<TEntity>) stellen die Konsistenz bidirektionaler Verweise für 1:n-Beziehungen und 1:1-Beziehungen sicher. Verwendet das Objektmodel EntitySet<TEntity> oder EntityRef<TEntity> nicht und ist ein umgekehrter Verweis vorhanden, ist es Ihre Aufgabe, diesen bei Aktualisierung der Beziehung mit dem vorwärts gerichteten Verweis konsistent zu halten.

Wenn Sie den erforderlichen Verweis und den entsprechenden Fremdschlüssel aktualisieren, müssen Sie deren Übereinstimmung sicherstellen. Eine InvalidOperationException-Ausnahme wird ausgelöst, wenn die beiden Elemente zum Zeitpunkt des Aufrufs von SubmitChanges nicht synchron sind. Obwohl die Werte von Fremdschlüsseln für die Aktualisierung der zugrunde liegenden Zeile ausreichen, müssen Sie die Referenz ändern, um die Konnektivität des Objektgraphen und die bidirektionale Konsistenz von Beziehungen zu erhalten.

Siehe auch

Konzepte

Insert-, Update- und Delete-Operationen (LINQ to SQL)

Weitere Ressourcen

Hintergrundinformationen (LINQ to SQL)