エンティティフレームワーク(4.3.1)で従来のデータアクセスコードを徐々に置き換える段階にあります。場合によっては、1つの作業単位で両方のデータアクセス方法を使用することを避けることはできません。理想的には、これは1つのトランザクションで実行する必要があります。ただし、古いコードでは、作業単位が完了し、EFが独自のトランザクションを管理するときにCommit()
を呼び出すSqlTransaction
が使用されます。TransactionScope内のSqlTransaction.Commitを無視する
私たちはTransactionScope
に「古い」コードと「新しい」コードをラップすることを考えました。ただし、TransactionScope
が完了していなくても、周囲のCommitはTransactionScope
が常に実行されます。このコードスニペットは、私の問題を示しています:scope.Complete()
がヒットしていないとき
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();
}
}
更新ステートメントはをまだコミットしています。
したがって、TransactionScope
を使用して、古いデータアクセスコードとコンテキスト内のSaveChanges
を強制的に1つのトランザクションで実行することはできません。 または、SqlTransaction.Commitステートメントを無効にする方法はありますか?
TransactionScopeとSqlTransactionについてもっと多くの記事があることは知っていますが、すべて(正しく言うと)、TransactionScopeを使用する場合、SqlTransactionを使用する必要はありません。しかし、ここではSqlTransactionを使用しないオプションはありません。私たちは、独自のフレームワークであるSqlTransaction
をコミットしていますが、トランザクションメカニズムにフックするAPIはありません。
少なくとも接続にアクセスできますか? –
@LadislavMrnkaいいえ、設定ファイルの接続文字列は別です。 –