Я не уверен, что вам здесь действительно нужно несколько контекстов.Вы заметили, что в документах EF Core есть это заметное предупреждение:
Предупреждение
EF Core не поддерживает несколько параллельных операций, выполняемых натот же экземпляр контекста.Вы должны всегда ждать завершения операции, прежде чем начинать следующую операцию.Обычно это делается с помощью ключевого слова await
в каждой асинхронной операции.
Это не совсем точно, или, скорее, это просто вводит в заблуждение.На самом деле вы можете запускать параллельные запросы для одного экземпляра контекста.Проблема заключается в отслеживании изменений EF и исправлении объектов.Эти типы вещей не поддерживают одновременное выполнение нескольких операций, так как им нужно иметь стабильное состояние для работы при выполнении своей работы.Однако это действительно ограничивает вашу способность делать определенные вещи.Например, если вы выполняете параллельные запросы сохранения / выбора, результаты могут быть искажены.Возможно, вы не вернете вещи, которые действительно есть сейчас, или отслеживание изменений может быть испорчено во время попытки создания необходимых операторов вставки / обновления и т. Д. Однако, если вы выполняете неатомарные запросы, такие как выборки в независимых таблицахКак вы и хотели, здесь нет реальной проблемы, особенно если вы не планируете выполнять дальнейшие операции, такие как редактирование выбранных объектов, и просто планируете вернуть их в представление или что-то в этом роде.
Если вы действительно решаете, что вам нужны отдельные контексты, ваша лучшая ставка - это новый контекст с использованием.Я на самом деле не пробовал этого раньше, но вы должны быть в состоянии внедрить DbContextOptions<AmsdbaContext>
в ваш класс, где происходят эти операции.Он уже должен быть зарегистрирован в коллекции служб, поскольку он внедряется в ваш контекст, когда коллекция служб создает его.Если нет, вы всегда можете просто создать новый:
var options = new DbContextOptionsBuilder()
.UseSqlServer(connectionString)
.Build()
.Options;
В любом случае, тогда:
List<Tbl1> tbl1data;
List<Tbl2> tbl2data;
List<Tbl3> tbl3data;
using (var tbl1Context = new AmsdbaContext(options))
using (var tbl2Context = new AmsdbaContext(options))
using (var tbl3Context = new AmsdbaContext(options))
{
var tbl1task = tbl1Context.Tbl1.ToListAsync();
var tbl2task = tbl2Context.Tbl2.ToListAsync();
var tbl3task = tbl3Context.Tbl3.ToListAsync();
tbl1data = await tbl1task;
tbl2data = await tbl2task;
tbl3data = await tbl3task;
}
Лучше использовать await
для получения фактического результата.Таким образом, вам даже не нужно WaitAll
/ WhenAll
/ etc.и вы не блокируете вызов Result
.Поскольку задачи возвращаются горячими или уже запущены, достаточно просто отложить вызовы до тех пор, пока они не будут созданы, достаточно, чтобы купить параллельную обработку.
Просто будьте осторожны с этим, чтобы выбрать все, что вам нужно в течение использования.Теперь, когда EF Core поддерживает отложенную загрузку, если вы используете это, попытка получить доступ к ссылке или свойству коллекции, которое не было загружено, вызовет ObjectDisposedException
, так как контекст исчезнет.