modest violet

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

modest violet

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

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

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

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

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

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を開始しようとしてエラーになってしまうと解釈しています。


所感


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

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