modest violet

読者です 読者をやめる 読者になる 読者になる

modest violet

開発者としてのあれこれや、日々の雑記など

your future hasn't written yet. no one's has.
by Emmett Lathrop "Doc" Brown

【技術メモ】DapperとContextTransaction 解決編

Dev Dev-技術メモ

一晩寝てスッキリしたら、あっさり解決した。

こういう所は昔っから変わらないのかも。

shin21.hatenablog.com

解決した方法

先に解決した方法を記載します。

Database.UseTransaction メソッド を使用すればオーケーのようです。

// ConnectionがOpenしていない場合はOpen
if (db.Database.Connection.State != System.Data.ConnectionState.Open)
{
    db.Database.Connection.Open();
}

// IDbTransactionでトランザクション開始
using (var tran = db.Database.Connection.BeginTransaction())
{
    try
    {

        // この一文が大事!
    // EntityFramework側に外部トランザクションを渡します
        db.Database.UseTransaction(tran);

        // EntityFrameworkでの処理(例)
        db.hogehoge.Attach(domainModel);
        db.Entry(domainModel).State = EntityState.Modified;
        db.SaveChanges();

        // Dapperでの処理(例) (SQL Client?)
    // IDbTransactionを引数で渡す
        var query = "Update hoge Set 省略 ";
        db.Database.Connection.Execute(query, new {hoge = hoge}, tran)

        trn.Commit();

    }
    catch
    {
        trn.Rollback(); 
    }

}

Database.UseTransaction メソッド

https://msdn.microsoft.com/ja-jp/library/dn220057(v=vs.113).aspx

Entity Framework で外部トランザクション内でコマンドを実行する必要がある場合、ユーザーは、Database オブジェクトの外部で作成されたデータベース トランザクションを渡すことができます。 または、null を渡して、フレームワークのそのトランザクションの情報をクリアします。

UseTransaction が無い場合


下記のエラーとなります。

"SqlConnection はパラレル トランザクションをサポートしません。"


既に同一コネクションでDbTransactionが開始されているのに、EntityFramework側でもContextTransactionを開始しようとしてエラーになってしまうと解釈しています。


所感


自分にとっては新しい事の連続で、その度に壁が現れて大変・・・。

でも登り切る時は達成感があって良いですね。