Ami*_*mit 98 c# transactions dapper
我想在多个表上运行多个insert语句.我正在使用dapper.net.我没有看到任何方法来处理与dapper.net的交易.
请分享您对如何使用dapper.net进行交易的想法.
the*_*ric 95
这里的代码片段:
using System.Transactions;
....
using (var transactionScope = new TransactionScope())
{
DoYourDapperWork();
transactionScope.Complete();
}
Run Code Online (Sandbox Code Playgroud)
请注意,您需要添加对System.Transactions程序集的引用,因为默认情况下不引用它.
ANe*_*ves 88
我更喜欢通过直接从连接获取事务来使用更直观的方法:
// 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();
}
Run Code Online (Sandbox Code Playgroud)
New*_*per 68
在 Dapper 中有 3 种进行交易的方法。
您可以从官方教程网站了解有关这些交易方式的更多信息
以下是交易方式的细分,供参考
1. 交易简单
在此示例中,您在现有数据库连接上创建一个事务,然后将该事务传递给 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();
}
}
Run Code Online (Sandbox Code Playgroud)
2. 从交易范围来看交易
如果您想创建事务范围,则需要在创建数据库连接之前执行此操作。创建事务范围后,您可以简单地执行所有操作,然后执行一次调用来完成事务,然后事务将提交所有命令
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();
}
Run Code Online (Sandbox Code Playgroud)
3. 使用 Dapper 事务
在我看来,这是在代码中实现事务的最有利的方法,因为它使代码易于阅读且易于实现。SQL 事务有一个扩展实现,称为 Dapper 事务(您可以在此处找到),它允许您直接运行事务中的 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();
}
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ite 18
您应该可以使用,TransactionScope因为Dapper只运行ADO.NET命令.
using (var scope = new TransactionScope())
{
// insert
// insert
scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)
考虑到您的所有表都在单个数据库中,我不同意TransactionScope这里的一些答案中建议的解决方案.请参阅此答案.
TransactionScope通常用于分布式交易; 跨越不同数据库的事务可能在不同的系统上.这需要在操作系统和SQL Server上进行一些配置,否则这将无法正常工作.如果所有查询都针对单个数据库实例,则不建议这样做.
但是,对于单个数据库,当您需要在不受您控制的事务中包含代码时,这可能很有用.对于单个数据库,它也不需要特殊配置.
connection.BeginTransaction是针对单个数据库实现事务(在C#,VB.NET等中)的ADO.NET语法.这不适用于多个数据库.
所以,connection.BeginTransaction()是更好的方式去.
处理事务的更好方法是实现UnitOfWork,如本答案中所述.
丹尼尔的回答对我来说按预期工作。为了完整起见,这里有一个片段,它演示了使用事务范围和 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
48539 次 |
| 最近记录: |