Параллельные асинхронные запросы с GraphQL для .NET и EF Core 3.0

Резюме

В настоящее время я переношу проект на AspNetCore 3.0 и столкнулся с проблемой с GraphQL для .NET ParallelExecutionStrategy при запросе нескольких вещей в одном запросе. В проекте используется сервер MSSQL в качестве хранилища данных, и доступ к нему осуществляется через Entity Framework Core 3.0. Я получаю следующую ошибку:

Вторая операция началась в этом контексте до завершения предыдущей. Обычно это вызвано тем, что разные потоки используют один и тот же экземпляр DbContext.

Я могу решить проблему, если использую IDocumentExecuter и изменю ParallelExecutionStrategy для ожидания каждого отдельного выполнения с Task.WhenAll на await ExecuteNodeAsync (https://github.com/graphql-dotnet/graphql-dotnet/blob/master/src/GraphQL/Execution/ParallelExecutionStrategy.cs#L27).

Пример запроса, который я пытаюсь выполнить:

query {
  thingA {
    id
  }
  thingB {
    id
  }
}

Изменить:

Использование DbContextPool, похоже, тоже не решает проблему:

services.AddDbContextPool<DBCONTEXT>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("CONNECTIONSTRING")));

person Ganhammar    schedule 22.10.2019    source источник


Ответы (3)


Если вы используете встроенный контейнер внедрения зависимостей, вам следует рассмотреть возможность использования IServiceScopeFactory<T>. По сути, это тот же подход, что и ответ на основе "StructureMap" Ганхаммара, за исключением того, что это не "локатор услуг". (Относительно простой) код IServiceScopeFactory<T> находится здесь, а другой ответ, связанный с этим вопросом, - здесь.

person Granger    schedule 11.03.2020

Мы используем StructureMap для внедрения зависимостей, который создает новый DbContext для HttpRequest, но нам нужен уникальный DbContext для каждого запроса, решение заключалось в создании вложенного контейнера и запросе зависимостей через вложенный контейнер.

public Constructor(IContainer container) => _dbContext = container.GetNestedContainer()
    .GetInstance<DbContext>();
person Ganhammar    schedule 22.10.2019

Посмотрите мою реализацию, которая решает эту проблему. Хитрость заключается в создании области видимости на уровне распознавателя https://github.com/fenomeno83/graphql-dotnet-globalization-demo

person Alessandro Lazzara    schedule 13.08.2020