Dapper - массовая вставка новых предметов и возврат новых идентификаторов
Я использую Dapper, чтобы добавить несколько новых студентов в одном попадании дБ, используя этот метод:
db.ExecuteAsync(@"INSERT Student(Name,Age) values (@Name,@Age)",
students.Select(s => new { Name = s.Name, Age = s.Age })
);
Но проблема у меня нет новых идентификаторов.
Могу ли я сделать один удар по дб и еще как получить новые идентификаторы?
И если нет, то каков наиболее эффективный способ выполнения такой массовой вставки?
2 ответа
Это не массовая вставка; в основном это просто сокращение, которое разворачивает цикл; хотя интересно (возможно), можно попросить его передать эту последовательность, если в вашем соединении включен "MARS". Без конвейера это в основном сокращение для:
foreach(var obj in students.Select(s => new { Name = s.Name, Age = s.Age }))
{
await db.ExecuteAsync(@"INSERT Student(Name,Age) values (@Name,@Age)", obj);
}
в этом случае вы могли бы также использовать Query
или же ExecuteScalar
чтобы получить SCOPE_IDENTITY()
,
С конвейером это более тонко; он делает то же самое, но с несколькими выдающимися командами одновременно (это только await
s, когда отставание заполнено, или когда были выполнены все команды).
Массовая вставка не возвращает идентификаторы. Вы можете рассмотреть возможность использования табличного параметра и использования INSERT
с OUTPUT
пункт, чтобы вставить весь DataTable
данных за один раз (получение идентификаторов в процессе), но с отрицательной стороны: это предполагает использование DataTable
;п
Отказ от ответственности: я владелец проекта Dapper Plus
Как ответил Марк, нет
BulkInsert
в Даппере.
Однако этого можно добиться с помощью Dapper Plus (библиотека является коммерческой).
Вам нужно указать в сопоставлении, какой столбец является идентификатором (чтобы идентификатор автоматически заполнялся для объекта)
// MAP once
DapperPlusManager.Entity<Invoice>().Identity(x => x.InvoiceID);
connection.BulkInsert(invoices, x => x.InvoiceMeta, x => x.InvoiceItems);
Можно даже автоматически распространять идентификатор, указав распространение идентификатора на
true
// MAP once
DapperPlusManager.Entity<Invoice>().Identity(x => x.InvoiceID, true);
connection.BulkInsert(invoices, x => x.InvoiceMeta, x => x.InvoiceItems);
В таком случае,
InvoiceItem
будет автоматически иметь
InvoiceID
также заселены.
Вы можете узнать больше о распространении идентичности здесь: https://dapper-plus.net/getting-started-identity-propagation