簡體   English   中英

實體框架樂觀並發異常處理

[英]Entity Framework Optimistic Concurrency Exception Handling

我正在嘗試解決EF 6上的樂觀並發控制問題。我目前想捕獲DBUpdateConcurrencyException ,然后刷新實體。 但是我目前正在收到此異常:

System.InvalidOperationException:要刷新的對象集合中索引0處的元素的EntityKey屬性值為空,或者未附加到此ObjectStateManager。

這是顯示目的的簡化代碼:

using (var dbContextTransaction = dbContext.Database.BeginTransaction(System.Data.IsolationLevel.Serializable))
{
    try
    {
        dbContext.Commit();
    }
    catch(DbUpdateConcurrencyException ex)
    {
        ((IObjectContextAdapter)KnowledgebaseContext).ObjectContext.Refresh(RefreshMode.StoreWins, en);
        dbContextTransaction.Rollback();
    }
}

我在Google或SO上找不到太多關於此例外的信息。 任何幫助,將不勝感激。

我已經能夠通過觀察來解決這個問題, 這個這個 關於此功能的文檔非常少。

所以這是場景(我們假設已經有一個TimeStamp列,其值隨每次數據庫更新而更新):

UserA讀取Entity1並開始進行更改。 在UserA進行更改時,userB讀取Entity1,對其進行更改並將其保存到數據庫中。 現在,UserA想要保存她的更改,但是根據定義,現在她讀取的確切實體不再存在。 原因是該實體的存在也取決於TimeStamp列,該列不再是舊值。 因此,當我嘗試刷新UserA已知存在的Entity1時,我遇到了異常,並且也無法Refresh

現在,我們將討論現有更新實體的並發問題的兩種可能解決方案:

  • 忽略用戶A的更改(商店獲勝) :這基本上意味着從數據庫Refresh實體。 為了做到這一點,應該用新的駐留在數據庫中的用戶覆蓋UserA上下文中Entity1的TimeStamp字段,然后嘗試從服務器刷新信息。 這樣,可以在Entity1中找到並檢索並填充正確的實體,從而覆蓋本地更改。 在這里尋找另一種方法。
  • 覆蓋數據庫上的更改(客戶端獲勝) :在這里,我們將覆蓋TimeStamp字段,然后再次嘗試更新。 這樣,EF將不再將更新檢測為沖突,並且服務器上的數據將被覆蓋。 前面提到的鏈接也包含這種情況的示例。

我不完全確定為什么使用Refresh方法時會出現異常。 我改用SetValuesGetDatabaseValues等,問題解決了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM