EF 6 - Как правильно выполнять параллельные запросы
При создании отчета я должен выполнить 3 запроса, которые связаны с отдельными объектами одного и того же контекста. Поскольку они довольно тяжелые, я решил использовать .ToListAsync();
, чтобы они запускались параллельно, но, к моему удивлению, я получаю исключение из этого...
Каков правильный способ параллельного выполнения запросов с использованием EF 6? Должен ли я вручную запускать новые задачи?
Изменить 1
Код в основном
using(var MyCtx = new MyCtx())
{
var r1 = MyCtx.E1.Where(bla bla bla).ToListAsync();
var r2 = MyCtx.E2.Where(ble ble ble).ToListAsync();
var r3 = MyCtx.E3.Where(ble ble ble).ToListAsync();
Task.WhenAll(r1,r2,r3);
DoSomething(r1.Result, r2.Result, r3.Result);
}
Ответы
Ответ 1
Проблема заключается в следующем:
EF не поддерживает обработку нескольких запросов через один и тот же объект DbContext. Если ваш второй асинхронный запрос к тому же экземпляру DbContext запускается до того, как первый запрос завершится (и в этом вся суть), вы получите сообщение об ошибке, которое ваш запрос обрабатывает в отношении открытого DataReader.
Источник: https://visualstudiomagazine.com/articles/2014/04/01/async-processing.aspx
Вам нужно будет изменить код так:
async Task<List<E1Entity>> GetE1Data()
{
using(var MyCtx = new MyCtx())
{
return await MyCtx.E1.Where(bla bla bla).ToListAsync();
}
}
async Task<List<E2Entity>> GetE2Data()
{
using(var MyCtx = new MyCtx())
{
return await MyCtx.E2.Where(bla bla bla).ToListAsync();
}
}
async Task DoSomething()
{
var t1 = GetE1Data();
var t2 = GetE2Data();
await Task.WhenAll(t1,t2);
DoSomething(t1.Result, t2.Result);
}
Ответ 2
Проверьте https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/enabling-multiple-active-result-sets
Из документации:
Чередование операторов операторов SELECT и BULK INSERT разрешается. Тем не менее, язык манипулирования данными (DML) и определение данных операторы языка (DDL) выполняются атомарно.
Тогда приведенный выше код сработает, и вы получите выигрыш в производительности при чтении данных.