2016-05-13 121 views
3

我有一個命令服務類,它利用工作單元模式,通過實體框架用各種方法更新數據庫(本例中爲SQL Azure)。EF6嵌套事務

命令服務通過引用一個dbcontext實例來實例化,該實例的生命週期由我選擇的DI框架管理。

一些命令服務類的方法包裝的多個更新到數據庫的事務中,例如:

public void UpdateStuff(someEntity) 
{ 
    using(var tx = _db.Database.BeginTransaction()) 
    { 
     //Some updates to db 
     _db.SaveChanges(); 
     //Some other updates to db 
     _db.SaveChanges(); 
     tx.Commit(); 
    } 
} 

現在,一些方法調用從他們的交易中的命令類的其他方法,例如:

public void UpdateWithSomeCascadingStuff(someOtherEntity) 
{ 
    using(var tx = _db.Database.BeginTransaction()) 
    { 
     //Some updates to db 
     _db.SaveChanges(); 

     //Some other cascading logic and updates to db 
     var relatedEntityToUpdate = _query.GetSomeEntityToUpdate(someOtherEntity); 
     UpdateStuff(relatedEntityToUpdate); 
     _db.SaveChanges(); 
     tx.Commit(); 
    } 
} 

顯然,通過這樣做,我爲同一個DbContext實例嵌套了EF事務。

這是否被支持,它會導致任何麻煩?我可以採取其他方法嗎?

更新: 我使用EF6代碼第一次

回答

1

的EntityFramework的DBContexts本身同時實現的UnitOfWork和信息庫模式。

EF6中的上下文還自動將事務中的所有提交包裝在自身中(如果它不是其中的一部分)。

所以,不,你不應該在多個工作單元之間共享上下文。他們應該各自擁有自己的。

UPDATE

如果你試圖在你得到同樣的DbContext開始重複的事務:

An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll 

Additional information: The connection is already in a transaction and cannot participate in another transaction. EntityClient does not support parallel transactions. 

所以,不,你不能做你所要求的。

+0

謝謝,但這不能回答我的問題。 –

+1

EF隱藏在客戶端代碼的接口後面(因爲我需要能夠輕鬆刷出存儲機制而不影響客戶端代碼),並且還有一些CQRS正在進行。因此,我必須「包裝」其UOW實施。如何,爲什麼和正確這是一個太長的討論。我知道EF在SaveChanges之前在單個事務中包裝指令。在我的情況下,我有多個SaveChanges調用,需要在單個事務中進行包裝。再一次 - 不是在這裏捍衛設計 - 我只是想知道我是否可以在另一個嵌套EF6交易。 –

+1

我擴大了我的答案。希望有助於更好地回答你的問題 –