TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2274 2.59K
День 1881. #ЗаметкиНаПолях
Массовая Вставка в C# и EF Core. Начало

Независимо от того, создаёте ли вы платформу анализа данных, переносите устаревшую систему или привлекаете новых пользователей, вероятно, наступит момент, когда вам потребуется вставить огромный объём данных в БД. Традиционные методы слишком медленные. Поэтому необходимо понимание методов быстрой массовой вставки в C#. Сегодня рассмотрим несколько вариантов.

Примечание: Мы не будем рассматривать некоторые крайние варианты, вроде ручной генерации SQL запросов или использования параметров, возвращающих табличные значения (Table-Valued parameters).

Допустим, нам нужно вставить множество экземпляров класса User в соответствующую таблицу БД.

1. Простой (плохой) пример EF Core
Для сравнения рассмотрим простейший (плохой) вариант, где пользователи добавляются по одному:
using var ctx = new AppDbContext();
foreach (var u in GetUsers())
{
ctx.Users.Add(u);
await ctx.SaveChangesAsync();
}

Результаты ужасные (как и ожидалось из-за множества запросов в БД):
  100 пользователей - 20 мс,
1000 – 260 мс,
10000 – 8,86 с.

Большее количество проверять бессмысленно, они занимают слишком много времени. Возьмём это за пример, как не надо делать массовую вставку.
*Заметьте, что время приведено только для сравнения между вариантами.

2. Добавление всех и сохранение в EF Core
Можно поправить пример выше, сначала добавив все записи в контекст, а затем 1 раз вызвав SaveChanges().
…
foreach (var u in GetUsers())
context.Users.Add(u);
await ctx.SaveChangesAsync();

Результаты:
    100 - 2 мс,
1000 - 18 мс,
10000 - 203 мс,
100000 - 2,13 с,
1000000 - 21,56 с.


3. AddRange в EF Core
Мы можем добавить в контекст сразу всю коллекцию, используя метод AddRange:
…
ctx.Users.AddRange(GetUsers());
await context.SaveChangesAsync();

Результаты аналогичны примеру выше, но код короче.

4. EF Core Bulk Extensions
Библиотеку EF Core Bulk Extensions можно использовать для повышения производительности. Кстати, она позволяет делать не только массовую вставку. Библиотека с открытым кодом, но платная для коммерческого использования. Для нашего варианта подойдёт метод BulkInsertAsync:
…
await context.BulkInsertAsync(GetUsers());

Результаты впечатляющие:
    100 - 1.9 мс,
1000 - 8 мс,
10000 - 76 мс,
100000 - 742 мс,
1000000 - 8,3 с.


Окончание следует…

Источник:
https://www.milanjovanovic.tech/blog/fast-sql-bulk-inserts-with-csharp-and-ef-core
  • 👍 22
More from @netdeveloperdiary
  1. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  2. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  3. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  4. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  5. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  6. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →