複数のテーブルで複数の挿入ステートメントを実行したいと思います。私はdapper.netを使用しています。dapper.netでトランザクションを処理する方法がわかりません。
トランザクションの使用方法に関するアイデアをdapper.netと共有してください。
複数のテーブルで複数の挿入ステートメントを実行したいと思います。私はdapper.netを使用しています。dapper.netでトランザクションを処理する方法がわかりません。
トランザクションの使用方法に関するアイデアをdapper.netと共有してください。
ここにコードスニペットがあります:
using System.Transactions;
....
using (var transactionScope = new TransactionScope())
{
DoYourDapperWork();
transactionScope.Complete();
}
System.Transactions
デフォルトでは参照されていないため、アセンブリへの参照を追加する必要があることに注意してください。
接続から直接トランザクションを取得することで、より直感的なアプローチを使用することを好みました。
// 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();
}
TransactionScope
DapperはADO.NETコマンドのみを実行するため、使用できるはずです。
using (var scope = new TransactionScope())
{
// open connection
// insert
// insert
scope.Complete();
}
TransactionScope
すべてのテーブルが単一のデータベースにあることを考えると、ここでのいくつかの回答で提案されている解決策には同意しません。この回答を参照してください。
TransactionScope
通常、分散トランザクションに使用されます。異なるデータベースにまたがるトランザクションは、異なるシステム上にある可能性があります。これには、オペレーティングシステムとSQL Serverでいくつかの構成が必要です。これがないと、これは機能しません。すべてのクエリがデータベースの単一インスタンスに対するものである場合、これは推奨されません。
ただし、単一のデータベースでは、これは、制御できないトランザクションにコードを含める必要がある場合に役立つことがあります。単一のデータベースでは、特別な構成も必要ありません。
connection.BeginTransaction
単一のデータベースに対してトランザクション(C#、VB.NETなど)を実装するためのADO.NET構文です。これは、複数のデータベース間では機能しません。
だから、connection.BeginTransaction()
行くためのより良い方法です。
トランザクションを処理するさらに良い方法は、この回答で説明されているようにUnitOfWorkを実装することです。
Dapperでトランザクションを実行するには3つのアプローチがあります。
これらのトランザクションアプローチの詳細については、公式チュートリアル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();
}
}
ダニエルの答えは私にとって期待通りに機能しました。完全を期すために、トランザクションスコープと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