大部分时间使用实体框架SaveChanges()
足够了。这将创建一个事务,或加入任何环境事务,并在该事务中执行所有必要的工作。
有时虽然SaveChanges(false) + AcceptAllChanges()
配对很有用。
最有用的地方是您想要跨两个不同上下文执行分布式事务的情况。
IE。像这样的东西(不好):
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Do something with context2
//Save and discard changes
context1.SaveChanges();
//Save and discard changes
context2.SaveChanges();
//if we get here things are looking good.
scope.Complete();
}
If context1.SaveChanges()
成功了但是context2.SaveChanges()
失败则整个分布式事务被中止。但不幸的是实体框架已经放弃了对context1
,因此您无法重播或有效记录失败。
但如果你将代码更改为如下所示:
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Do something with context2
//Save Changes but don't discard yet
context1.SaveChanges(false);
//Save Changes but don't discard yet
context2.SaveChanges(false);
//if we get here things are looking good.
scope.Complete();
context1.AcceptAllChanges();
context2.AcceptAllChanges();
}
虽然打电话给SaveChanges(false)
向数据库发送必要的命令,上下文本身不会更改,因此您可以在必要时再次执行此操作,或者您可以询问ObjectStateManager
如果你想。
这意味着如果事务实际上抛出异常,您可以通过重试或记录每个上下文的状态来进行补偿ObjectStateManager
某处。
See my https://twitter.com/adjames 博客文章 https://learn.microsoft.com/en-gb/archive/blogs/alexj/savechangesfalse了解更多。