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. - Для больших объемов данных стоит избегать загрузки всей таблицы в память.
Добавить комментарий