精简版和多个相同命令的执行?

时间:2019-06-29 09:35:20

标签: c# .net ado.net dapper

dapper如何多次执行同一命令?正如我在下面编写的那样,插入sql,并使用list参数调用Dapper的execute方法,因此我将插入3个对象。

问题:dapper是否进行3次往返Sql Server的执行以执行3次插入,还是以某种方式将其发送为1次往返以调用3次插入?

我只是想知道,像这样使用它是否比仅foreach有优势,并且可以一次调用一个插入,或者是否完全相同。

Version 1.

var sqlInsert = $"INSERT INTO Book (Id, Title) Values (@Id, @Title)";
var parameters = new List<Book> { new Book("Damian Book", 123), new Book("XXX Book", 156), new Book("Zonk BOok", 167) };

connection.Execute(sqlInsert, parameters);

Version 2.

foreach (var book in parameters)
{
    connection.Execute(sqlInsert, book)
}

版本1和版本2是否全部相同?

1 个答案:

答案 0 :(得分:2)

当您将IEnumerable传递到Execute以插入多个项目时,每个项目都会被独立插入。就是说,您介绍的两种情况没有太大的区别。

Dapper通过接受IEnumerable来简化多个项目的插入。它没有在内部实现批量插入之类的功能。

看看this文章:

  

但是这种方法将每个命令作为一个独立的事务发送,这可能会导致在执行一个或多个语句时出错的情况下产生不一致。解决方法是使用IDBTransaction对象创建一个涵盖所有执行的显式事务。性能和可伸缩性要比仅执行一个传递一组对象的命令要差(由于网络延迟和较长的事务处理),但至少可以保证一致性。

     

但是,由于Dapper支持SQL Server的Table-Valued-Parameters和JSON,因此我建议您在需要将值数组传递给参数的情况下使用其中之一。我将在以后的文章中讨论它们,敬请期待。

     

现在,如果必须传递一个包含10.000个或更多值的数组怎么办?在这里,正确的选择是使用大容量负载,更具体地说,对于SQL Server,使用BULK INSERT命令,但不幸的是,Dapper本身不支持该命令。解决方法是仅在此处使用常规的SqlBulkCopy类,即可完成。

或者,您可以考虑使用Dapper Plus - Bulk Insert之类的工具。

您可能会了解有关批量插入的更多信息以及实现此here的技巧。此外,Dapper supports TVPs。如果您使用RDBMS,请使用它。

回答您的评论:

  

如果我创建事务并在其中调用多个插入,那么事务是否进行一次往返数据库的调用以调用所有事务?还是插入仍将一一执行?

事务与批量插入无关。如果在事务中包装代码块(有问题的任何版本),结果将不会改变。整个事务将提交或回滚。如果没有事务,则如果某处之间的操作失败,则可能会遇到一致性问题。通过将代码包装在事务中,您可以避免此问题。您的核心问题-批量插入保持原样。