【发布时间】:2016-03-08 22:59:15
【问题描述】:
我已经看到很多关于在事务中多次调用 dbContext.SaveChanges 的问题和建议。 有人说应该避免这种情况。这篇深度文章真的值得一读http://mehdi.me/ambient-dbcontext-in-ef6/
在我的特定场景中,实体 B 具有对实体 A 的 Id 引用
在创建场景期间,我创建 A 并调用 savechanges 以获取数据库分配的 A.Id。 然后我像 new B(A.Id,....) 一样创建实体 B 并再次调用 savechanges。在伪代码中可能看起来像这样
using(var tx = dbContext.BeginTransaction())
{
var a = new A();
dbContext.Add(a); //a.Id is null
dbContext.saveChanges(); // a.Id has now been initialized
var b = new B(a.Id); //I want to create b in a valid state so a.Id cannot be null
dbContext.SaveChanges();
tx.Commit();
}
(我知道伪代码缺少异常处理逻辑……)
为什么会出现这个问题? 是不是因为savechanges不能回滚?
我知道我可以改造,但这是不可能的,因为我们与一些遗留系统共享数据库,所以数据库不能轻易更改,如果可能的话!
什么是替代解决方案?
【问题讨论】:
-
鉴于 Entity Framework 确实支持显式事务,问题是什么?您似乎为您似乎错过的功能编写伪代码,而您的伪代码实际上调用了一个存在的方法。你打扰文档了吗? msdn.microsoft.com/en-us/data/dn456843.aspx 标题为“使用事务(从 EF6 开始)”。
-
SaveChanges 使用内部事务。更改分配是已经原子的。实际的问题是什么?仅仅因为有人在某处写了您应该多次致电
SaveChanges并不意味着它是正确的。事实上,为什么你的代码会调用它两次??。 -
如果您使用适当的关系,则没有理由分配 ID。 EF 将识别新的/修改的类并生成 SQL 语句,以正确的顺序插入新对象
-
感谢 cmets。是的,我已阅读有关交易的文章。在某些情况下,我可能更喜欢仅通过 Id 引用而不具有对象关系。我的代码第一次调用 SaveChanges 以获取 A 的 ID,以便我可以初始化 B。我有两个问题:1)我不清楚为什么调用 savechages 两次是不好的。 2)解决问题的替代方法。我很欣赏你提出的建议..
标签: c# entity-framework transactionscope