ASP.NET MVCプロジェクトにUnit Unit of Workパターンを組み込もうとしていますが、これはEntity Frameworkの他の典型的なUoW設計とは少し異なります。Entity FrameworkのUnitOfWorkパターン(直接SQLクエリを使用)
私のデータベースは、実際にはEF friendlyではないという点で、高度に正規化された純粋なリレーショナル構造を持っています。このため、エンティティにマッピングされたビューが作成されました。問合せ時にすべてのEFおよびLINQの良さが維持されますが、エンティティを更新するときに(例:Context.Database.ExecuteSqlCommand
)のダイレクトSQLクエリを使用する必要があります。
これは私のUoWデザインに挑戦しています。私が知る限り、EFでのUoWへの一般的なアプローチは、が呼び出されたときに限り、基本的にContext.SaveChanges()
を呼び出すことです。このようにして、すべての追跡されたエンティティの変更は、一度に1つのトランザクションとしてデータベースにコミットされます。
Context.Database.ExecuteSqlCommand
を使用しているため、エンティティを更新するたびにトランザクションが発生しますすぐに、したがってUoW全体が失われます。私は例をあげる:EFと
伝統UOW:EFと
public void CreateOrder()
{
var customer = new Customer();
// this only adds the entity to the Context for tracking
// e.g. Context.Customers.Add(customer);
UoW.CustomerRepo.Add(customer);
// this too only adds the entity to the Context
var order = new Order();
UoW.OrderRepo.Add(order);
// Commit. this internally calls Context.SaveChanges()
// sending all changes to the db in a single transaction
// Perhaps also with a TransactionScope.
UoW.Commit();
}
マイUOW:
public void CreateOrder()
{
var customer = new Customer();
// this inserts a customer to the db immediately
// e.g. Context.Database.ExecuteSqlCommand(insertSql);
UoW.CustomerRepo.Add(customer);
// This too inserts an order immediately
var order = new Order();
UoW.OrderRepo.Add(order);
// There is no point calling Context.SaveChanges()
// here as all my changes are already executed with direct sql.
UoW.Commit();
}
誰でも同様の問題に遭遇したのか?ここではUoWを放棄して、すべてのリポジトリアクションを単一のTransactionScope
にまとめてください。
これを見てください(61票の回答):http://stackoverflow.com/questions/815586/entity-framework-using-transactions-or-savechangesfalse-and-acceptallchanges – Klinger
EFコマンドを発行する前にトランザクションを開始している間は、ExecuteSqlCommandを使用します。私が間違っていないと、EFに変更を保存するように求められたら、既存のトランザクションを使用します。 – Klinger
この投稿はとても役に立ちました。私はUoWを捨てて、トランザクションスコープだけに行きました。 –