共用方式為


儲存變更及管理並行 (Entity Framework)

實體架構 會實作開放式並行存取 (Optimistic Concurrency) 模型。這表示,資料來源中的資料不會被鎖定。但是根據預設,物件服務會將物件變更儲存到資料庫,而不會檢查是否有並行。如果是可能遇到高程度並行的屬性,我們建議您最好使用 ConcurrencyMode="fixed" 屬性在概念層中定義實體屬性,如下列範例所示:

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

當使用這個屬性時,物件服務會檢查資料庫中是否有變更,然後再將變更儲存到資料庫。任何衝突的變更都會導致 OptimisticConcurrencyException。如需詳細資訊,請參閱 HOW TO:管理物件內容中的資料並行存取 (Entity Framework)。如果您定義使用預存程序的 實體資料模型 來對資料來源進行更新,也會發生 OptimisticConcurrencyException。在這種情況下,當用來執行更新的預存程序報告並未更新任何資料列時,便會引發例外狀況。如需詳細資訊,請參閱預存程序支援 (Entity Framework)

當您在這類高並行案例中進行更新時,我們建議您經常呼叫 Refresh。當您呼叫 Refresh 時,RefreshMode 會控制變更散佈的方式。StoreWins 選項將會使得物件服務使用資料庫中的對應值來覆寫物件快取中的所有資料。反之,ClientWins 選項會使用資料來源中的最新值來取代快取中的原始值。如此可確保物件快取中所有已變更的資料都可以順利儲存回資料來源,其方式是消除快取中的資料變更與資料來源中相同資料的變更兩者之間的衝突。

如果對資料來源更新可能會修改屬於此物件內容中其他物件的資料,請在呼叫 SaveChanges 方法之後再呼叫 Refresh 方法。例如,在 AdventureWorks Sales Model 中加入新的 SalesOrderDetail 時,便會觸發更新 SubTotal 資料行來反映具有新項目的小計。在這種情況下,請呼叫 Refresh 方法並且傳遞此訂單的 SalesOrderHeader 物件。這樣可確保將觸發產生的值送回到物件內容中的 SalesOrderHeader 物件。

物件服務會追蹤對快取中的物件所做的變更。當呼叫 SaveChanges 方法時,物件服務會嘗試將變更合併回資料來源。當快取中加入了物件或重新整理物件之後,如果物件快取中的資料變更與資料來源中的變更衝突,則 SaveChanges 會失敗,並引發 OptimisticConcurrencyException。這樣會導致整個交易復原。當 OptimisticConcurrencyException 發生時,您應該處理它,其方式是呼叫 Refresh,並指定是否應該藉由保留物件資料中的資料 ClientWins 或使用資料來源中的資料更新物件快取 StoreWins,以解決衝突狀況,如下列範例所示:

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

如果無法在資料來源中順利建立加入到 ObjectContext 的物件,SaveChanges 可能會產生 UpdateException。如果具有關聯性所指定之外部索引鍵的資料列已經存在,就可能發生這種情況。發生這種情況時,您無法使用 Refresh 來更新物件內容中這個加入的物件。請改用 MergeOptionOverwriteChanges 值重新載入此物件。

如需有關管理物件內容的詳細資訊,請參閱 HOW TO:管理物件內容中的資料並行存取 (Entity Framework)

物件服務也會接受之前使用 System.Transactions 命名空間所定義的交易。如需詳細資訊,請參閱在物件服務中管理交易 (Entity Framework)

另請參閱

概念

加入、修改和刪除物件 (Entity Framework)

其他資源

使用物件 (Entity Framework)