【问题标题】:Custom atomic UPDATE commands inside SaveChanges()SaveChanges() 中的自定义原子更新命令
【发布时间】:2012-11-03 08:02:26
【问题描述】:

由于各种原因,当我在 DbContext 上调用 SaveChanges 时,我需要能够执行多个自定义 SQL UPDATE 命令。我希望这以原子方式发生,因此常规的SaveChanges 和 SQL 都成功,或者都不成功。

虽然我不知道如何做到这一点。到目前为止,我尝试过的是这个和各种变体:

EF transactions — Gist

这里的错误是(在ExecuteSqlCommand 调用上):

当分配给命令的连接处于挂起的本地事务中时,ExecuteNonQuery 要求该命令具有事务。

好的,很公平。 ExecuteSqlCommand 没有接受事务的重载。所以,我安装了 Dapper 包并用这个 Dapper 调用替换了有问题的行,然后我传入了事务:

this.Database.Connection
  .Execute("insert into Tests (Foo, Bar) values ('test', 2)", 
  transaction: tran);

但现在错误发生在 base.SaveChanges() 上,它给了我以下信息:

SqlConnection 不支持并行事务。

显然SaveChanges 总是创建一个新事务,即使我已经在数据上下文的连接上创建了一个?

有什么方法可以实现我想要的吗?

我使用的是 Entity Framework 5.0 Code First。

【问题讨论】:

标签: c# entity-framework transactions dapper savechanges


【解决方案1】:

在所有操作周围包裹一个TransactionScope。此类是 .NET 事务的通用抽象。 EF 和SqlConnection 将自动加入。请务必寻找最佳实践,因为存在一些陷阱,例如意外触发分布式事务。

【讨论】:

  • 是的,这正是我的担心,因为我过去曾触发过 MSDTC,并且有点回避我猜想的整个事情。我什至还没有尝试过,因为我认为它会创建两个事务,而不是一个。显然我对TransactionScope 的理解不正确:) 我会试一试。
  • @JulianR 将其视为对您技能的投资:) 无论如何,诀窍是永远不要使用多个(打开的)SqlConnection。由于 EF 对此很愚蠢,您可能需要在输入 TransactionScope 之前调用 ObjectContext db; db.Connection.Open()。给自己写一些单元测试来确认。关闭 MSDTC 以使测试能够失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-05
  • 1970-01-01
  • 2017-05-26
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
相关资源
最近更新 更多