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

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

このトピックの例には、Adventure Works Sales Model が使用されています。この例のコードを実行するには、あらかじめプロジェクトに AdventureWorks Sales Model を追加し、Entity Framework を使用するようにプロジェクトを構成しておく必要があります。具体的な方法については、「Entity Framework プロジェクトを手動で構成する方法」および「Entity Data Model を手動で定義する方法 (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.SalesOrderHeader.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 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

        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.SalesOrderHeader.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)
オブジェクトの使用 (Entity Framework タスク)