132

複数のテーブルで複数の挿入ステートメントを実行したいと思います。私はdapper.netを使用しています。dapper.netでトランザクションを処理する方法がわかりません。

トランザクションの使用方法に関するアイデアをdapper.netと共有してください。

4

6 に答える 6

118

ここにコードスニペットがあります:

using System.Transactions;    
....    
using (var transactionScope = new TransactionScope())
{
    DoYourDapperWork();
    transactionScope.Complete();
}

System.Transactionsデフォルトでは参照されていないため、アセンブリへの参照を追加する必要があることに注意してください。

于 2012-04-28T13:32:44.810 に答える
113

接続から直接トランザクションを取得することで、より直感的なアプローチを使用することを好みました。

// This called method will get a connection, and open it if it's not yet open.
using (var connection = GetOpenConnection())
using (var transaction = connection.BeginTransaction())
{
    connection.Execute(
        "INSERT INTO data(Foo, Bar) values (@Foo, @Bar);", listOf5000Items, transaction);
    transaction.Commit();
}
于 2013-11-18T12:36:45.367 に答える
20

TransactionScopeDapperはADO.NETコマンドのみを実行するため、使用できるはずです。

using (var scope = new TransactionScope())
{
   // open connection
   // insert
   // insert
   scope.Complete();
}
于 2012-04-28T13:31:05.730 に答える
11

TransactionScopeすべてのテーブルが単一のデータベースにあることを考えると、ここでのいくつかの回答で提案されている解決策には同意しません。この回答を参照してください。

  1. TransactionScope通常、分散トランザクションに使用されます。異なるデータベースにまたがるトランザクションは、異なるシステム上にある可能性があります。これには、オペレーティングシステムとSQL Serverでいくつかの構成が必要です。これがないと、これは機能しません。すべてのクエリがデータベースの単一インスタンスに対するものである場合、これは推奨されません。
    ただし、単一のデータベースでは、これは、制御できないトランザクションにコードを含める必要がある場合に役立つことがあります。単一のデータベースでは、特別な構成も必要ありません。

  2. connection.BeginTransaction単一のデータベースに対してトランザクション(C#、VB.NETなど)を実装するためのADO.NET構文です。これは、複数のデータベース間では機能しません。

だから、connection.BeginTransaction()行くためのより良い方法です。

トランザクションを処理するさらに良い方法は、この回答で説明されているようにUnitOfWorkを実装することです。

于 2017-11-07T11:40:10.563 に答える
9

Dapperでトランザクションを実行するには3つのアプローチがあります。

  1. 簡単な取引
  2. トランザクションスコープからのトランザクション
  3. Dapperトランザクションの使用(追加のnugetパッケージ と最も好まれるアプローチ

これらのトランザクションアプローチの詳細については、公式チュートリアルWebサイトを参照してください。

参考までに、トランザクションアプローチの内訳を示します

1.簡単なトランザクション

この例では、既存のdb接続でトランザクションを作成してから、そのトランザクションをdapperのExecuteメソッド(オプションのパラメーター)に渡します。

すべての作業が完了したら、トランザクションをコミットするだけです。

string sql = "INSERT INTO Customers (CustomerName) Values (@CustomerName);";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
    connection.Open();
    
    using (var transaction = connection.BeginTransaction())
    {
        connection.Execute(sql, new {CustomerName = "Mark"}, transaction: transaction);
        connection.Execute(sql, new {CustomerName = "Sam"}, transaction: transaction);
        connection.Execute(sql, new {CustomerName = "John"}, transaction: transaction);
        
        transaction.Commit();
    }
}

2.トランザクションスコープからのトランザクション

トランザクションスコープを作成する場合は、db接続を作成する前にこれを行う必要があります。トランザクションスコープを作成したら、すべての操作を実行し、1回の呼び出しでトランザクションを完了するだけで、すべてのコマンドがコミットされます。

using (var transaction = new TransactionScope())
{
    var sql = "INSERT INTO Customers (CustomerName) Values (@CustomerName);";

    using (var connection = My.ConnectionFactory())
    {
        connection.Open();

        connection.Execute(sql, new {CustomerName = "Mark"});
        connection.Execute(sql, new {CustomerName = "Sam"});
        connection.Execute(sql, new {CustomerName = "John"});
    }

    transaction.Complete();
}

3.Dapperトランザクションの使用

これは、コードを読みやすく、実装しやすいため、コードでトランザクションを実行するための最も好ましいアプローチです。Dapper Transaction(ここにあります)と呼ばれるSQLトランザクションの拡張実装があります。これにより、トランザクションから直接SQL実行を実行できます。

string sql = "INSERT INTO Customers (CustomerName) Values (@CustomerName);";

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
    connection.Open();
    
    using (var transaction = connection.BeginTransaction())
    {
        transaction.Execute(sql, new {CustomerName = "Mark"});
        transaction.Execute(sql, new {CustomerName = "Sam"});
        transaction.Execute(sql, new {CustomerName = "John"});

        transaction.Commit();
    }
}
于 2021-05-10T17:09:46.480 に答える
5

ダニエルの答えは私にとって期待通りに機能しました。完全を期すために、トランザクションスコープとdapperを使用したコミットとロールバックを示すスニペットを次に示します。

using System.Transactions;
    // _sqlConnection has been opened elsewhere in preceeding code 
    using (var transactionScope = new TransactionScope())
    {
        try
        {
            long result = _sqlConnection.ExecuteScalar<long>(sqlString, new {Param1 = 1, Param2 = "string"});

            transactionScope.Complete();
        }
        catch (Exception exception)
        {
            // Logger initialized elsewhere in code
            _logger.Error(exception, $"Error encountered whilst executing  SQL: {sqlString}, Message: {exception.Message}")

            // re-throw to let the caller know
            throw;
        }
    } // This is where Dispose is called 
于 2015-12-01T23:13:17.230 に答える