gpt4 book ai didi

c# - 加载后简单删除时出现 dbUpdateConcurrencyException

转载 作者:太空宇宙 更新时间:2023-11-03 15:31:26 28 4
gpt4 key购买 nike

我已经阅读了一些关于可能导致 dbUpdateConcurrencyException 的问题和文章而且它们似乎都与我的代码中发生的事情无关。我对使用 Entity Framework 6.0 的 CRUD 操作进行了简单的功能测试。

我的 [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 的外键.我猜这是相关的;删除契约(Contract)会改变 Customer实体,自Customer实体具有契约(Contract)属性的集合。但同样,我在删除契约(Contract)后重新加载客户;因此它们不会在加载和删除之间被修改。

我曾尝试一次删除一个项目而不是使用 RemoveRange() ;第一次删除时发生同样的错误。我试过打电话 Reload()在特定的 Customer在尝试删除那个 Customer 之前的实体;同样的结果。

另请注意,这适用于所有其他不删除合约的测试。因此,在删除客户之前删除所有契约(Contract)就可以正常工作。只有在删除清理中的其余契约(Contract)之前删除了单个契约(Contract)。

这是完整的错误消息/堆栈跟踪:

System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions. ---> System.Data.Entity.Core.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions.. Result StackTrace:
at System.Data.Entity.Internal.InternalContext.SaveChanges() at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() at System.Data.Entity.DbContext.SaveChanges()

内部异常具有完全相同的类型和消息,具有此堆栈跟踪:

at 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, Func2 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, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction) at 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) at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options) at System.Data.Entity.Internal.InternalContext.SaveChanges()

更新

我能够通过传递 DbContext 让它工作/解决它我在我的数据设置/拆卸中使用到正在测试的方法。换句话说,错误似乎是因为有一个 DbContext用于测试设置/拆卸,以及一个不同的 DbContext用于被测试的代码。

但是,这并没有真正回答我的任何问题。我宁愿不必绕过我的 DbContext确保它是一样的;有没有一种方法可以让我的上下文从实际数据库中刷新/加载,而不仅仅是使用它所知道的?而且,这根本无法解释为什么删除契约(Contract)可以正常工作,而且它只会在删除客户时失败。

最佳答案

这个错误是因为测试设置运行时正在加载测试设置和拆卸使用的DBContext。不同的上下文会在设置和拆卸之间更改数据库,并且因为第一个上下文是在设置期间加载的,所以它基于数据库的“旧”版本,即测试运行之前的版本。

解决方案是不要让拆卸使用与安装程序使用的相同的 DBContext。 Teardown 应该加载自己的新 DBContext,以便根据最新数据加载它。

我曾假设重要的是从数据库加载要删除的客户时数据的状态。但显然重要的是加载 DBContext 时数据的状态。

关于c# - 加载后简单删除时出现 dbUpdateConcurrencyException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33697855/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com