我对EF不太熟悉,但我正在使用EF的一些基本功能。最近我得到了关于EF6交易的https://msdn.microsoft.com/en-us/data/dn456843.aspx。
之前我正在使用SaveChanges(),因为我知道它将在事务中包装操作。但我注意到我的一些同事正在使用Database.BeginTransaction()。我搜索周围的东西并得到以下结果,但我不能确认它是正确的。
SaveChanges()是否仍能正常工作,当SaveChanges无法满足此帖http://www.binaryintellect.net/articles/165bb877-27ee-4efa-9fa3-40cd0cf69e49.aspx中单个事务中包含多个SaveChanges的要求时,是否使用了BeginTransaction?
在那篇文章中,由于db上下文是相同的,我还可以添加两个对象并调用一次SaveChanges(),这也可以正常工作吗?我想如果我们要处理多个db上下文,那么我们最好使用BeginTransaction在一个事务中处理多个SaveChanges()?
编辑:
如果我想在一次交易中添加两个,以下是不正确的?为什么?
public void CreateAnimals()
{
context.Set<Cat>.Add(new Dog());
context.Set<Cat>.Add(new Cat());
context.SaveChanges();
}
编辑2:
我的主要问题:当我们可以使用SaveChanges()时必须使用BeginTransaction()吗? Database.BeginTransaction vs Transactions.TransactionScope没有提到SaveChanges
答案 0 :(得分:3)
即使您未明确指定事务,SaveChanges也始终在事务中执行其DML。
向上下文添加实体不会进行数据库调用。执行DML的唯一时间是调用SaveChanges时。因此,您发布的代码是原子的(您称之为#34;正确&#34;)。
多个上下文无法共享事务(轻松)。在大多数情况下,您不应该使用多个上下文。默认情况下,在一个上下文和一个事务中执行您的工作。
答案 1 :(得分:0)
你不应该共享上下文。这不是线程安全的。如果您需要可重用的代码,可能会或可能不会合并到原子操作中,请实例化单个上下文(它们非常轻量级)并在代码中更高级别管理原子性。
public void Foo()
{
using ( var context = factory.CreateContext()
{
context.Set<Cat>.Add(new Cat());
context.SaveChanges();
}
}
public void Bar()
{
using ( var context = factory.CreateContext()
{
context.Set<Cat>.Add(new Dog());
context.SaveChanges();
}
}
public void CreateAnimals()
{
using ( var context = factory.CreateContext() )
{
var tran = context.Database.BeginTransaction();
Foo();
Bar();
tran.Commit();
}
}