[英]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
。
現在,我們將討論現有更新實體的並發問題的兩種可能解決方案:
Refresh
實體。 為了做到這一點,應該用新的駐留在數據庫中的用戶覆蓋UserA上下文中Entity1的TimeStamp
字段,然后嘗試從服務器刷新信息。 這樣,可以在Entity1中找到並檢索並填充正確的實體,從而覆蓋本地更改。 在這里尋找另一種方法。 TimeStamp
字段,然后再次嘗試更新。 這樣,EF將不再將更新檢測為沖突,並且服務器上的數據將被覆蓋。 前面提到的鏈接也包含這種情況的示例。 我不完全確定為什么使用Refresh
方法時會出現異常。 我改用SetValues
和GetDatabaseValues
等,問題解決了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.