Даппер и выполнение нескольких одинаковых команд? - PullRequest
1 голос
/ 29 июня 2019

Как dapper выполняет несколько раз одну и ту же команду? Как я уже писал ниже, вставьте sql и вызовите метод execute Dapper с параметрами списка, поэтому я вставлю 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 Ответ

2 голосов
/ 29 июня 2019

Когда вы передаете IEnumerable в Execute для вставки нескольких элементов, каждый элемент вставляется независимо.Тем не менее, нет большой разницы в двух представленных вами сценариях.

Dapper просто облегчает вставку нескольких элементов, принимая IEnumerable.Он не реализует внутренне что-то вроде массовой вставки.

Посмотрите на эту статью:

Но при таком подходе каждая команда отправляется как одна отдельнаяодна транзакция, которая может вызвать несоответствия в случае ошибки при выполнении одного или нескольких операторов.Обходной путь здесь заключается в использовании объекта IDBTransaction для создания явной транзакции, которая охватывает все выполнения.Производительность и масштабируемость будут хуже, чем выполнение только одной команды, передающей массив объектов (из-за задержки в сети и, следовательно, более длительных транзакций), но, по крайней мере, согласованность будет гарантирована.

Но поскольку Dapper поддерживает Table-Valued в SQL Server-Параметры, а также JSON, я рекомендую использовать один из них, если вам нужно передать массив значений в параметр.Я буду обсуждать их в следующих статьях, так что следите за обновлениями.

А что если вам нужно передать массив, скажем, 10.000 значений или больше?Правильный выбор здесь - использовать массовую загрузку, а более конкретно, с SQL Server - команду BULK INSERT, которая, к сожалению, изначально не поддерживается Dapper.Обходной путь - просто использовать обычный класс SqlBulkCopy, и все готово.

В качестве альтернативы, вы можете рассмотреть возможность использования такого инструмента, как Dapper Plus - Bulk Insert .

Вы можете узнать больше о массовой вставке и взломе для достижения этой цели здесь .Кроме того, Dapper поддерживает TVPs .Если ваша СУБД работает, используйте ее.

Чтобы ответить на ваш комментарий:

Если я создаю транзакцию и вызываю несколько вставок внутри нее, выполняется ли транзакция 1 поездка в базу данных для вызовавсе они?Или вставки все равно будут выполняться одна за другой?

Транзакция не имеет ничего общего с массовой вставкой.Если вы поместите свой блок кода (любую версию, о которой вы упомянули) в транзакцию, результат не изменится ... ну, кроме одной.Вся транзакция будет либо зафиксирована, либо отката.Без транзакции вы можете столкнуться с проблемами согласованности, если где-то между операциями произойдет сбой.Оборачивая свой код в транзакцию, вы просто избегаете этой проблемы.Ваша основная проблема - «Массовая вставка» остается без изменений.

...