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



我对EF不太熟悉,但我正在使用EF的一些基本功能。最近我收到了这个https://msdn.microsoft.com/en-us/data/dn456843.aspx关于EF6中的交易。

我以前使用过SaveChanges(),因为我知道它会将操作包装在事务中。但我注意到我的一些同事正在使用Database.BeginTransaction()。我四处搜索,得到了以下结果,但我无法确认它是正确的。

是SaveChanges()仍然可以正常工作,当SaveChanges不能满足本文中在单个事务中包装多个SaveChanges的要求时,使用BeginTransactionhttp://www.binaryintellect.net/articles/165bb877-27ee-4efa-9fa3-40cd0cf69e49.aspx?

在那篇文章中,由于db上下文是相同的,我还可以添加两个对象并调用SaveChanges()一次,这也可以吗?我想,如果我们要处理多个数据库上下文,那么我们最好使用BeginTransaction在一个事务中处理多个SaveChanges()?

编辑:

如果我想在一个交易中添加两个,以下内容是不正确的?为什么?

public void CreateAnimals()  
{  
    context.Set<Cat>.Add(new Dog());  
    context.Set<Cat>.Add(new Cat());   
    context.SaveChanges();  
}

编辑2:
我的主要问题是:我们什么时候可以使用SaveChanges(),什么时候必须使用BeginTransaction()Database.BeginTransaction与Transactions.TransactionScope未提及SaveChanges

SaveChanges始终在事务中执行其DML,即使您没有显式指定事务。

向上下文中添加实体不会调用数据库。执行DML的唯一时间是调用SaveChanges时。因此,您发布的代码是原子代码(您称之为"正确的")。

多个上下文无法(轻松)共享一个事务。无论如何,在大多数情况下都不应该使用多个上下文。默认情况下,在一个上下文和一个事务中执行您的工作。

您不应该共享上下文。这不是线程安全。如果您需要可重复使用的代码,这些代码可能会也可能不会组合到原子操作中,请实例化各个上下文(它们非常轻量级),并在代码的更高级别管理原子性。

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

最新更新