C# 加载后简单删除的dbUpdateConcurrencyException
我读过几篇关于可能导致C# 加载后简单删除的dbUpdateConcurrencyException,c#,.net,entity-framework,concurrency,entity-framework-6,C#,.net,Entity Framework,Concurrency,Entity Framework 6,我读过几篇关于可能导致dbUpdateConcurrencyException异常的问题和文章,它们似乎都与我的代码中发生的事情无关。我对CRUD操作进行了简单的功能测试,使用的是实体框架6.0 My[TestInitialize]插入一些数据,My[TestCleanup]删除相同的数据。这对于我的所有测试都很好,除了删除记录的测试。当调用该测试的清理时,它抛出一个dbUpdateConcurrencyException 我的测试清理方法如下: var contracts = this
dbUpdateConcurrencyException
异常的问题和文章,它们似乎都与我的代码中发生的事情无关。我对CRUD操作进行了简单的功能测试,使用的是实体框架6.0
My[TestInitialize]
插入一些数据,My[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
- 在尝试删除实体之前,我正在加载要删除的实体。它们不可能在加载和尝试删除之间被修改。我的理解是,当一个实体在加载和试图删除之间被修改时,就会发生这种异常
合同
确实有一个指向客户ID
的外键。我猜这是相关的;删除合同将更改客户
实体,因为客户
实体具有合同属性集合。但是,在删除合同后,我再次加载新的客户;因此,它们不是在加载和删除之间被修改的
我尝试过一次删除一个项目,而不是使用RemoveRange()
;第一次删除时也会发生相同的错误。在试图删除一个特定的客户
实体之前,我已经尝试调用了Reload()
;同样的结果
还要注意,这对于所有其他不删除合同的测试都很有效。因此,在删除客户之前删除所有合同正常工作。只有在删除单个合同后,才能在清理中删除其余合同
这是完整的错误消息/堆栈跟踪:
System.Data.Entity.Infrastructure.DbUpdateConcurrencyException:System.Data.Entity.Infrastructure.DbUpdateConcurrencyException:存储更新、插入或删除语句影响了意外的行数(0)。自加载实体后,实体可能已被修改或删除。有关了解和处理乐观并发异常的信息,请参阅。-->System.Data.Entity.Core.OptimisticConcurrencyException:存储更新、插入或删除语句影响了意外的行数(0)。自加载实体后,实体可能已被修改或删除。有关了解和处理乐观并发异常的信息,请参阅。。
结果堆栈跟踪:位于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.ValidateRowsInfected(Int64行受影响,UpdateCommand源) 位于System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()处 位于System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.b__2(UpdateTranslator ut) 位于System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult,Func
2 updateFunction)
位于System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update()处
位于System.Data.Entity.Core.Objects.ObjectContext.b__35()
在System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func
1 Func,IDbExecutionStrategy executionStrategy,Boolean startLocalTransaction,Boolean releaseConnectionOnSuccess)
位于System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions选项、IDBEcutionStrategy executionStrategy、Boolean startLocalTransaction)
在System.Data.Entity.Core.Objects.ObjectContext.c__DisplayClass2a.b__27()中
在System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1操作)中
位于System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions选项,布尔值executeInExistingTransaction)
位于System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions)
位于System.Data.Entity.Internal.InternalContext.SaveChanges()处
更新
通过将我在数据设置/拆卸中使用的DbContext
传递给正在测试的方法,我能够让它工作/绕过它。换句话说,错误似乎是因为有一个DbContext
用于测试设置/拆卸,而另一个DbContext
用于测试代码
然而,这并没有真正回答我的任何问题。我宁愿不必传递我的
DbContext
来确保它是相同的;有没有一种方法可以让我的上下文从实际数据库中刷新/加载,而不仅仅是使用它知道的内容?而且,这根本不能解释为什么删除合同可以正常工作,它只会在删除客户时失败。导致此错误的原因是测试设置和拆卸使用的DBContext在测试设置运行时被加载。不同的上下文会在安装和拆卸之间更改数据库,因为第一个上下文是在安装过程中加载的,所以它基于数据库的“旧”版本,即运行测试之前的版本
解决方案是不让拆卸使用与安装u的DBContext相同的DBContext