現在、レガシーデータアクセスコードをエンティティフレームワーク(4.3.1)に徐々に置き換えています。場合によっては、1つの作業単位で両方の方法のデータアクセスを使用することを避けられません。理想的には、これは1つのトランザクションで実行する必要があります。ただし、古いコードは、作業単位が完了し、EFが独自のトランザクションを管理するときにSqlTransaction
呼び出すsを使用します。Commit()
そこで、「古い」コードと「新しい」コードをでラップすることを考えましたTransactionScope
。ただし、周囲のコミットは、完了しTransactionScope
ていなくても常に実行されTransactionScope
ます。このコードスニペットは私の問題を示しています。
using (var conn = new SqlConnection("connection string"))
{
conn.Open();
using (var scope = new TransactionScope())
{
using (var tr = conn.BeginTransaction())
{
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tr;
cmd.CommandText = "some update statement";
cmd.ExecuteNonQuery();
}
tr.Commit();
}
// In reality the code above is part of a legacy DAL, immutable.
// (can't insert SaveChanges before tr.Commit).
context.SaveChanges();
if (<all ok>) // pseudo code for exception handling.
scope.Complete();
}
}
がヒットされない場合でも、updateステートメントはコミットされます。scope.Complete()
TransactionScope
そのため、どうやら、古いデータアクセスコードとSaveChanges
コンテキストからのを1つのトランザクションで強制的に実行するために使用することはできません。または、SqlTransaction.Commitステートメントを無効にする方法はありますか?
TransactionScopeとSqlTransactionに関する投稿が他にもあることは知っていますが、TransactionScopeを使用する場合、SqlTransactionを使用する必要はない(または推奨されない)とすべて(正しく)言っています。ただし、ここではSqlTransactionを使用しないことはできません。独自SqlTransaction
のをコミットし、トランザクションメカニズムにフックするAPIを持たないレガシーフレームワークがあります。