Share via


オブジェクト コンテキストでデータの同時実行制御を管理する方法 (Entity Framework)

このトピックでは、オブジェクト コンテキストで同時実行制御を管理する方法について説明します。 このトピックでは、SalesOrderHeader オブジェクトの Status プロパティが更新されたときに OptimisticConcurrencyException を生成して処理します。 詳細については、「変更の保存と同時実行制御の管理 (Entity Framework)」を参照してください。

The example in this topic is based on the Adventure Works Sales Model. To run the code in this example, you must have already added the AdventureWorks Sales Model to your project and configured your project to use the Entity Framework. To do this, complete the procedures in Entity Framework プロジェクトを手動で構成する方法 and 方法: モデル ファイルとマッピング ファイルを手動で定義する (Entity Framework).

OptimisticConcurrencyException を生成するには、概念マッピング ファイルで Status プロパティを変更する必要があります。

Status プロパティで同時実行制御チェックを有効にするには

  1. AdventureWorks.csdl ファイルを開き、SalesOrderHeader エンティティの定義を探します。

  2. 子の Status 要素を探し、次の属性を追加します。

    ConcurrencyMode="fixed"
    
  3. 変更内容を AdventureWorks.csdl に保存します。

  4. 次のコード例で、foreach ループ (Visual Basic の場合は For Each) の後にブレークポイントを設定し、アプリケーションをデバッグ モードで実行します。

  5. 実行が中断されたら、SQL Server Management Studio を使用し、AdventureWorks データベースに対して次の Transact-SQL コマンドを実行します。

    UPDATE Sales.SalesOrderHeader SET Status = 1 WHERE CreditCardApprovalCode IS NULL.
    
  6. プログラムの実行を再開します。

以上の手順に従った場合、SalesOrderHeader オブジェクトの Status プロパティに対する変更によって、OptimisticConcurrencyException が生成されます。

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());
    }
}

参照

概念

オブジェクトの使用 (Entity Framework)