2015-04-07 80 views
0

我不太熟悉有關EF,但我使用EF的一些基本功能。最近我收到了有關EF6交易的https://msdn.microsoft.com/en-us/data/dn456843.aspx何時使用EF 6中的BeginTransaction? VS的SaveChanges

我用的SaveChanges()之前,因爲我知道它會在一個事務包裹的操作。但我注意到我的一些同事正在使用Database.BeginTransaction()。我搜索了一些東西並得到了以下結果,但我無法確認它是正確的。

是否SaveChanges()仍然可以正常工作,並且在SaveChanges無法滿足要求時使用BeginTransaction,比如在本文中的單個事務中包裝多個SaveChanges http://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 vs Transactions.TransactionScope沒有提到的SaveChanges

回答

2

即使您未明確指定事務,SaveChanges也始終在事務中執行其DML。

添加實體上下文不會使數據庫調用。 DML執行的唯一時間是調用SaveChanges時。因此,您發佈的代碼是原子的(您稱之爲「正確」)。

多個上下文無法共享一個事務(很容易)。無論如何,在大多數情況下,您都不應該使用多個上下文。默認情況下在一個上下文和一個事務中執行您的工作。

+0

謝謝usr,解釋很清楚。但是我仍然想知道什麼時候應該使用BeginTransaction而不是SaveChanges,因爲SaveChanges也可以在一個事務中完成操作。 – woodwind

+0

當您想要以原子方式執行多個SaveChanges,或者您希望執行與其他事務相同的事務時的讀取操作。 – usr

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

感謝您的代碼。但我仍然想知道爲什麼我不能使用剛剛添加的代碼片段。我不認爲它與線程安全有關。 – woodwind

+0

「外部」上下文中的事務對「內部」上下文沒有影響,因爲實際上它們之間沒有關係。 – usr