Share via


Gewusst wie: Verwalten von Datenparallelität im Objektkontext (Entity Framework)

In diesem Thema wird anhand eines Beispiels erläutert, wie die Parallelität in einem Objektkontext verwaltet werden kann. In diesem Thema generieren und behandeln Sie eine OptimisticConcurrencyException bei der Aktualisierung der Status-Eigenschaft eines SalesOrderHeader-Objekts. Weitere Informationen finden Sie unter Speichern von Änderungen und Verwalten von Parallelität (Entity Framework).

Das Beispiel in diesem Thema beruht auf dem "AdventureWorks Sales"-Modell. Um den Code in diesem Beispiel auszuführen, müssen Sie Ihrem Projekt bereits das "AdventureWorks Sales"-Modell hinzugefügt und das Projekt für die Verwendung von Entity Framework konfiguriert haben. Führen Sie dazu die Verfahren in Gewusst wie: Manuelles Konfigurieren eines Entity Framework-Projekts und Gewusst wie: Manuelles Definieren der Modell- und Zuordnungsdateien (Entity Framework) aus.

Um eine OptimisticConcurrencyException erfolgreich zu generieren, müssen Sie die Status-Eigenschaft in der konzeptionellen Mapping-Datei ändern.

So aktivieren Sie die Parallelitätsprüfung für die Status-Eigenschaft

  1. Öffnen Sie die Datei AdventureWorks.csdl, und suchen Sie die Definition der SalesOrderHeader-Entität.

  2. Suchen Sie das untergeordnete Element Status, und fügen Sie das folgende Attribut hinzu:

    ConcurrencyMode="fixed"
    
  3. Speichern Sie die Änderungen an AdventureWorks.csdl.

  4. Legen Sie im folgenden Beispielcode einen Haltepunkt nach der foreach-Schleife (For Each in Visual Basic) fest, und führen Sie die Anwendung im Debugmodus aus.

  5. Wenn die Ausführung unterbrochen wird, verwenden Sie SQL Server-Management Studio, um den folgenden Transact-SQL -Befehl für die AdventureWorks-Datenbank auszuführen:

    UPDATE Sales.SalesOrderHeader SET Status = 1 WHERE CreditCardApprovalCode IS NULL.
    
  6. Starten Sie die Ausführung des Programms erneut.

Beispiel

Änderungen der Status-Eigenschaft des SalesOrderHeader-Objekts verursachen in diesem Beispiel eine OptimisticConcurrencyException, wenn das oben beschriebene Verfahren ausgeführt wird.

Using context As New AdventureWorksEntities()
    Try
        ' Perform an operation with a high-level of concurrency. 
        ' Change the status of all orders without an approval code. 
        Dim orders As ObjectQuery(Of SalesOrderHeader) = context.SalesOrderHeaders.Where("it.CreditCardApprovalCode IS NULL").Top("100")

        For Each order As SalesOrderHeader In orders
            ' Reset the order status to 4 = Rejected. 
            order.Status = 4
        Next
        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 generatedExceptionName 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

        For Each order As SalesOrderHeader In orders
            Console.WriteLine(("Order ID: " & order.SalesOrderID.ToString() & " Order status: ") + order.Status.ToString())
        Next
    Catch ex As UpdateException
        Console.WriteLine(ex.ToString())
    End Try
End Using
using (AdventureWorksEntities context =
    new AdventureWorksEntities())
{
    try
    {
        // Perform an operation with a high-level of concurrency.
        // Change the status of all orders without an approval code.
        ObjectQuery<SalesOrderHeader> orders =
            context.SalesOrderHeaders.Where(
            "it.CreditCardApprovalCode IS NULL").Top("100");

        foreach (SalesOrderHeader order in orders)
        {
            // Reset the order status to 4 = Rejected.
            order.Status = 4;
        }
        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");
        }

        foreach (SalesOrderHeader order in orders)
        {
            Console.WriteLine("Order ID: " + order.SalesOrderID.ToString()
                + " Order status: " + order.Status.ToString());
        }
    }
    catch (UpdateException ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

Siehe auch

Konzepte

Arbeiten mit Objekten (Entity Framework)