Параллельные вызовы dbcontext в ядре .NET Core EF

В проекте используются:

  • SQL-сервер
  • .NET ядро ​​3
  • Ядро EF

В моем проекте у меня есть миллионы данных/записей, которые мне нужны для параллельного запроса на чтение в API из 4 разных таблиц. DBContext имеет ограниченное время жизни, как это рекомендуется. Мне нужно сделать параллельные вызовы DBContext, но когда я пытаюсь, он говорит, что второй экземпляр запущен, когда один уже используется (поскольку время жизни ограничено).

  • Я пытался использовать AsNoTracking() для этих конкретных запросов, но все равно та же ошибка.
  • Я не могу использовать переходный Lifetime.
  • Проект использует шаблон репозитория, не может использовать новый экземпляр DBcontext в контроллерах.

    public MemberRepository(
        IMemberEntityMappingHelper memberEntityMappingHelper,
        IMapperExtension mapper,
        ProjectDBContext context)
        : base(context, mapper)
    {
        _memberEntityMappingHelper = memberEntityMappingHelper;
    }
        public List<MemberSummaryModel> GetMembers(int foreignKeyId)
    {
        List<MemberEntity> members = _context.Members
                                                                        .Include(x => x.Sample)
                                                                        .Where(x =>
                                                                          x.SampleForeignkeyId == foreignKeyId
                                                                          && x.IsDeleted == false)
                                                                        .ToList();
    
        return _memberEntityMappingHelper.EntityToSummaryModelList(members);
    }
    

Параллельные звонки -

Parallel.Invoke(() =>
{
// Read from table 1
}, 
() => 
{
// Read from table 2
});

Мне нужно оптимизировать мой код, чтобы улучшить время отклика.

  1. Есть ли способ запуска параллельных запросов (только чтение)?
  2. DbContext не является потокобезопасным, один экземпляр не может обновлять/создавать записи для одного экземпляра, но почему я не могу выполнять параллельные запросы на чтение?
  3. Сколько времени ожидается для получения 30 000 строк за раз (когда я использую все индексы)? Как я могу уменьшить его, у меня загрузка данных занимает 2 минуты?

person Ishika Jain    schedule 20.05.2020    source источник
comment
Если ваши экземпляры DbContext имеют Scoped и вы не делитесь ими между потоками, вы не должны видеть эту ошибку. Можете ли вы опубликовать упрощенную копию, демонстрирующую проблему?   -  person David Browne - Microsoft    schedule 20.05.2020
comment
Я вижу эту ошибку, когда делаю параллельный запрос на чтение, в это время используется общий доступ к dbcontext.   -  person Ishika Jain    schedule 20.05.2020
comment
В вашей строке подключения включено MultipleActiveResultSets?   -  person Roger Wolf    schedule 20.05.2020
comment
Я попробовал MultipleActiveResultSets, включив ту же ошибку - произошла одна или несколько ошибок. (Вторая операция началась в этом контексте до завершения предыдущей операции. Обычно это вызвано тем, что разные потоки используют один и тот же экземпляр DbContext.   -  person Ishika Jain    schedule 20.05.2020


Ответы (1)


DbContext не является потокобезопасным, один экземпляр не может обновлять/создавать записи для одного экземпляра, но почему я не могу выполнять параллельные запросы на чтение?

Потому что DbContext не является безопасным для Tthread. ПЕРИОД. Не "обновлять/создавать" - ВООБЩЕ. Многое из этого сводится к тому, что параллельные операторы SQL в одном DbConnection в конце не предполагаются, и MARS не меняет этого — он позволяет перекрывать результаты запроса, а не перекрывать выполнение запроса.

Сколько времени ожидается для получения 30 000 строк за раз (когда я использую все индексы)?

Индексы: Менее важны, чем размер объектов и ваше сетевое соединение. В прошлый раз я добавил, что это было полмиллиона записей за полсекунды, но эти записи были небольшими, И сетевое соединение было ОЧЕНЬ быстрым.

Есть ли способ запуска параллельных запросов (только чтение)?

Да, несколько подключений к БД, несколько DbContexts.

person TomTom    schedule 20.05.2020