共用方式為


HOW TO:管理物件內容中的資料並行存取 (Entity Framework)

本主題提供的範例將示範如何管理物件內容中的並行。 在這個主題中,您將在更新 SalesOrderHeader 物件的 Status 屬性時產生並處理 OptimisticConcurrencyException。 如需詳細資訊,請參閱儲存變更及管理並行存取 (Entity Framework)

本主題的範例是根據 Adventure Works Sales Model。 若要執行此範例中的程式碼,您必須已經將 AdventureWorks Sales Model 加入到專案中,並設定您的專案使用 Entity Framework。 若要這樣做,請完成 HOW TO:手動設定 Entity Framework 專案HOW TO:手動定義模型和對應檔 (Entity Framework) 中的程序。

若要順利產生 OptimisticConcurrencyException,您必須在概念對應檔中修改 Status 屬性。

若要針對 Status 屬性啟用並行檢查

  1. 開啟 AdventureWorks.csdl 檔案並且找出 SalesOrderHeader 實體的定義。

  2. 尋找 Status 子元素,並加入下列屬性:

    ConcurrencyMode="fixed"
    
  3. 將變更儲存到 AdventureWorks.csdl。

  4. 在下列範例程式碼中,於 foreach 迴圈 (Loop) (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());
    }
}

另請參閱

概念

使用物件