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