何时在EF 6中使用BeginTransaction? vs SaveChanges

时间:2015-04-07 03:14:30

标签: entity-framework

我对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

2 个答案:

答案 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();
    }
}