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

Другие вопросы по тегам