我讀過幾篇有關可能導致dbUpdateConcurrencyException
的事情的問題和文章,但他們中的任何一篇似乎都與我的代碼中發生的事情有關。我對我的CRUD操作進行了簡單的功能測試,這些操作使用Entity Framework 6.0。加載後簡單刪除時出現dbUpdateConcurrencyException
我的[TestInitialize]
插入了一些數據,我的[TestCleanup]
刪除了相同的數據。這適用於我所有的測試,除了刪除記錄的測試外。當這個測試的清理被調用時,它會拋出一個dbUpdateConcurrencyException
。
我的測試清理方法僅僅是這樣的:
var contracts = this.Context.Contract
.Where(c => c.EntryUserID == "FunctionalTests.TestData").ToList();
this.Context.Contract.RemoveRange(contracts);
this.Context.SaveChanges();
var customers = this.Context.Customer
.Where(c => c.EntryUserID == "FunctionalTests.TestData").ToList();
this.Context.Customer.RemoveRange(customers);
this.Context.SaveChanges(); //This throws dbUpdateConcurrencyException??
運行之前失敗從Context.Contract
刪除一條記錄測試。一對夫婦奇怪的事情:
- 的
Context.Contract
的清理工作得很好。這是Context.Customer
的打破,即使Customer.Contract
是在測試過程中被刪除的。 - 我試圖刪除它們之前立即加載要刪除的實體。它們不可能在加載和嘗試刪除之間進行修改。我的理解是,當一個實體在加載和嘗試刪除之間被修改時,會發生這種異常。
Contract
確實有一個外鍵到CustomerId
。我猜這是相關的;刪除合同將改變實體Customer
,因爲Customer
實體具有一系列合同屬性。但是,我再次在之後加載新客戶我刪除了合同;所以它們是而不是在加載和刪除之間被修改。
我試過一次刪除一個項目而不是用RemoveRange()
;同樣的錯誤發生在第一次刪除。在嘗試刪除Customer
之前,我已嘗試在特定的Customer
實體上調用Reload()
;相同的結果。
另請注意,對於不刪除合同的所有其他測試,此工作正常。因此,在刪除客戶之前刪除所有合同通常可以正常工作。只有在刪除清理中的其他合同之前刪除了單個合同之後。
這是完全錯誤信息/堆棧跟蹤:
System.Data.Entity.Infrastructure.DbUpdateConcurrencyException:System.Data.Entity.Infrastructure.DbUpdateConcurrencyException:商店更新,插入或刪除語句的影響意外的行數(0)。自實體加載後,實體可能已被修改或刪除。有關理解和處理樂觀併發異常的信息,請參閱http://go.microsoft.com/fwlink/?LinkId=472540。 ---> System.Data.Entity.Core.OptimisticConcurrencyException:存儲更新,插入或刪除語句會影響意外數量的行(0)。自實體加載後,實體可能已被修改或刪除。見http://go.microsoft.com/fwlink/?LinkId=472540的信息,理解和處理樂觀併發異常.. 結果堆棧跟蹤:在System.Data.Entity.Internal.InternalContext.SaveChanges
() 在System.Data.Entity.Internal.LazyInternalContext。調用SaveChanges() 在System.Data.Entity.DbContext.SaveChanges()
內部異常具有完全相同的類型和消息,與該堆棧跟蹤:
在System.Data.Entity的。 Core.Mapping.Update.Internal.UpdateTranslator.ValidateRowsAffected(Int64 rowsAffected,UpdateCommand source) at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() at System.Data.Entity.Core.EntityClient .Internal.EntityAdapter.b__2(UpdateTranslator ut) at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update [T](T noChangesResult,函數功能
2 updateFunction) at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update() at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__35() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func
1 FUNC,IDbExecutionStrategy executionStrategy,布爾startLocalTransaction,布爾releaseConnectionOnSuccess) 在System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions選項,IDbExecutionStrategy executionStrategy,布爾startLocalTransaction) 在System.Data.Entity.Core .Objects.ObjectContext。 <> c__DisplayClass2a.b__27() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute [TResult](Func`1 operation) at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options,Boolean executeInExistingTransaction ) 處System.Data.Entity.Internal.InternalContext.SaveChanges System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions選項) ()
更新
我能夠通過傳遞來讓它工作/解決它,我在我的數據設置/拆卸中使用了正在測試的方法。換句話說,這個錯誤似乎是因爲有一個DbContext
被用於測試設置/拆卸,而另一個DbContext
被用於被測試的代碼。
但是,這並沒有真正回答我的任何問題。我寧願不必傳遞我的DbContext
以確保它是相同的;有沒有一種方法可以告訴我的上下文從實際數據庫刷新/加載,而不僅僅是使用它所知道的內容?而且,這並不能解釋爲什麼刪除合同會正常工作,而且只能刪除客戶。
爲什麼在一個地方使用兩次SaveChanges()調用?我知道它不相關。順便說一句你有沒有檢查兩個DbContext實例的哈希碼? – CodeNotFound
@CodeNotFound我插入了另一個SaveChanges()以確認問題與試圖在合同被刪除之前刪除客戶沒有關係。最初它只有一個SaveChanges()。 – GendoIkari
請問您可以在dbUpdateConcurrencyException中向我們顯示確切的消息嗎?我知道這是一個併發異常,但有時你可以在InnerException消息中擁有大量信息。 – CodeNotFound