EFCore.BulkExtensions — это библиотека для Entity Framework Core, позволяющая выполнять массовые операции с базой данных (Bulk Insert, Update, Delete, Read) значительно быстрее, чем стандартные методы EF Core. Она использует BulkCopy для SQL Server и аналогичные оптимизированные механизмы для других СУБД, что значительно снижает накладные расходы, связанные с отслеживанием изменений (ChangeTracker).
Метод BulkRead в EFCore.BulkExtensions
Метод BulkRead предназначен для массового чтения данных из базы с использованием SqlBulkCopy (в случае MSSQL) или аналогичных механизмов для других СУБД.
Особенности работы BulkRead
- Оптимизирован для массового чтения – Использует
SqlBulkCopy(MSSQL) или аналогичные механизмы, что позволяет быстро загружать большие объемы данных. - Работает через временную таблицу – Загружаемые данные могут сравниваться с временной таблицей для фильтрации.
- Можно задать фильтры – Позволяет передавать список ключей для выборки (например, список
Id). - Не поддерживает стриминговую загрузку порциями – Он загружает сразу все подходящие записи в память.
Может ли BulkRead читать неограниченное количество записей?
Нет. Метод BulkRead не поддерживает ленивую загрузку (IQueryable) и загружает все данные в память, что может привести к OutOfMemoryException при больших объемах данных (например, 1 000 000 записей).
Можно ли получить всю таблицу порциями?
Стандартный BulkRead не умеет работать порционно. Однако можно организовать порционное чтение вручную:
Вариант с Skip и Take
csharpКопироватьРедактироватьconst int batchSize = 10000;
long totalRecords = dbContext.MyTable.Count();
for (int offset = 0; offset < totalRecords; offset += batchSize)
{
var batch = dbContext.MyTable
.OrderBy(x => x.Id) // важно для последовательного чтения
.Skip(offset)
.Take(batchSize)
.ToList();
// Обработка порции данных
}
Этот способ позволяет обойти ограничение по памяти.
Вариант с BulkRead и фильтрацией по ID
Если в таблице есть автоинкрементный Id, можно читать порциями через диапазоны:
csharpКопироватьРедактироватьconst int batchSize = 10000;
long minId = dbContext.MyTable.Min(x => x.Id);
long maxId = dbContext.MyTable.Max(x => x.Id);
for (long start = minId; start <= maxId; start += batchSize)
{
var batch = new List<MyTable>();
dbContext.BulkRead(batch, options => options
.Where(x => x.Id >= start && x.Id < start + batchSize));
// Обработка порции данных
}
Этот метод более эффективен, чем Skip + Take, так как не требует сортировки и пропуска строк.
Вывод
BulkReadне умеет работать с неограниченным числом записей – он загружает все найденные данные в память.BulkReadне поддерживает автоматическое чтение порциями.- Чтобы читать данные порциями, лучше использовать
Skip/Takeили фильтрацию по диапазону Id. - Для больших объемов данных стоит избегать загрузки всей таблицы в память.

Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.