Freigeben über


Speichern von Änderungen und Verwalten von Parallelität (Entity Framework)

Entity Framework implementiert ein Modell vollständiger Parallelität. Dies bedeutet, dass Daten in der Datenquelle nicht gesperrt werden. In der Standardeinstellung jedoch werden in Object Services Objektänderungen ohne Überprüfung der Parallelität in der Datenbank gespeichert. Daher wird für Eigenschaften, für die ein hoher Grad an Parallelität nötig sein kann, empfohlen, die Entitätseigenschaft auf der konzeptionellen Ebene mit dem Attribut ConcurrencyMode="fixed" zu definieren (siehe folgendes Beispiel):

<Property Name="Status" Type="Byte" Nullable="false" ConcurrencyMode="Fixed" />

Bei der Verwendung dieses Attributs wird die Datenbank von Object Services vor dem Speichern von Änderungen in der Datenbank auf Änderungen geprüft. Konflikte verursachende Änderungen lösen eine OptimisticConcurrencyException aus. Weitere Informationen finden Sie unter Gewusst wie: Verwalten von Datenparallelität im Objektkontext (Entity Framework). Eine OptimisticConcurrencyException kann auch dann auftreten, wenn ein Entitätsdatenmodell definiert wird, in dem gespeicherte Prozeduren zum Aktualisieren der Datenquelle verwendet werden. In diesem Fall wird die Ausnahme ausgelöst, wenn die zum Aktualisieren verwendete gespeicherte Prozedur meldet, dass keine Zeilen aktualisiert wurden. Weitere Informationen finden Sie unter Unterstützung für gespeicherte Prozeduren (Entity Framework).

Wenn in solchen Hochparallelitätsszenarios Aktualisierungen vorgenommen werden, wird empfohlen, Refresh häufig aufzurufen. Beim Aufruf von Refresh wird die Weitergabe von Änderungen von RefreshMode gesteuert. Die Option StoreWins führt dazu, dass in Object Services alle Daten im Objektcache mit den entsprechenden Werten aus der Datenbank überschrieben werden. Umgekehrt ersetzt die Option ClientWins die ursprünglichen Werte im Cache mit den aktuellen Werten aus der Datenquelle. So wird sichergestellt, dass alle geänderten Daten im Objektcache erfolgreich in der Datenquelle gespeichert werden können, da Konflikte zwischen Änderungen an den Daten im Cache und denen in der Datenquelle vermieden werden.

Die Refresh-Methode sollte nach dem Aufruf der SaveChanges-Methode aufgerufen werden, wenn Aktualisierungen der Datenquelle Daten ändern könnten, die zu anderen Objekten im Objektkontext gehören. Wenn z. B. im AdventureWorks Sales-Modell ein neues SalesOrderDetail hinzugefügt wird, wird die Spalte "SubTotal" von Triggern aktualisiert, damit das Teilergebnis das neue Element widerspiegelt. Rufen Sie in diesem Fall die Refresh-Methode auf, und übergeben Sie das SalesOrderHeader-Objekt für die Bestellung. Damit wird sichergestellt, dass von Triggern generierte Werte an das SalesOrderHeader-Objekt im Objektkontext zurückgesendet werden.

In Object Services werden die an den Objekten im Cache vorgenommenen Änderungen nachverfolgt. Beim Aufruf der SaveChanges-Methode führt Object Services Änderungen in der Datenquelle wieder zusammen. SaveChanges kann mit einer OptimisticConcurrencyException fehlschlagen, wenn Datenänderungen im Objektcache einen Konflikt mit Änderungen hervorrufen, die in der Datenquelle vorgenommen wurden, nachdem dem Cache Objekte hinzugefügt wurden oder Objekte darin aktualisiert wurden. In diesem Fall wird die gesamte Transaktion zurückgesetzt. Wenn eine OptimisticConcurrencyException auftritt, sollte Refresh aufgerufen und angegeben werden, ob der Konflikt aufgelöst werden soll, indem die Daten in den Objektdaten beibehalten werden (ClientWins), oder ob der Objektcache mit den Daten aus der Datenquelle aktualisiert werden soll (StoreWins) (siehe folgendes Beispiel):

Try
    ' Try to save changes, which may cause a conflict.
    Dim num As Integer = context.SaveChanges()
    Console.WriteLine("No conflicts. " + _
                      num.ToString() + " updates saved.")
Catch ex As OptimisticConcurrencyException
    ' Resolve the concurrency conflict by refreshing the 
    ' object context before re-saving changes. 
    context.Refresh(RefreshMode.ClientWins, orders)

    ' Save changes.
    context.SaveChanges()
    Console.WriteLine("OptimisticConcurrencyException " _
                      + "handled and changes saved.")
End Try
try
{
    // Try to save changes, which may cause a conflict.
    int num = context.SaveChanges();
    Console.WriteLine("No conflicts. " +
        num.ToString() + " updates saved.");
}
catch (OptimisticConcurrencyException)
{
    // Resolve the concurrency conflict by refreshing the 
    // object context before re-saving changes. 
    context.Refresh(RefreshMode.ClientWins, orders);

    // Save changes.
    context.SaveChanges();
    Console.WriteLine("OptimisticConcurrencyException "
    + "handled and changes saved");
}

SaveChanges kann eine UpdateException auslösen, wenn ein dem ObjectContext hinzugefügtes Objekt nicht in der Datenquelle erstellt werden kann. Dies kann auftreten, wenn eine Zeile mit dem von der Beziehung angegebenen Fremdschlüssel bereits vorhanden ist. In diesem Fall kann Refresh nicht zum Aktualisieren des hinzugefügten Objekts im Objektkontext verwendet werden. Laden Sie das Objekt stattdessen mit einem Wert von OverwriteChanges für MergeOption erneut.

Weitere Informationen zum Verwalten des Objektkontexts finden Sie unter Gewusst wie: Verwalten von Datenparallelität im Objektkontext (Entity Framework).

In Object Services werden auch Transaktionen berücksichtigt, die mit dem Namespace System.Transactions definiert wurden. Weitere Informationen finden Sie unter Verwalten von Transaktionen in Object Services (Entity Framework).

Siehe auch

Konzepte

Hinzufügen, Ändern und Löschen von Objekten (Entity Framework)

Weitere Ressourcen

Arbeiten mit Objekten (Entity Framework)