GraphQL Hot Chocolate - Entity Framework error: A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext
If you try to combine HotChocolate GrapQL implementation together with Entity Framework, a possible attempt could look like this:
Unfortunately this doesn't work the moment multiple resolvers kick in. When you try to resolve multiple queries/fields, chances are you end up with the following exception message:
"message": "A second operation was
started on this context before a previous operation completed. This is usually
caused by different threads concurrently using the same instance of DbContext.
For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.",
"stackTrace": " at
Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()\r\n
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()\r\n
at
Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1
asyncEnumerable, CancellationToken cancellationToken)\r\n at
Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1
asyncEnumerable, CancellationToken cancellationToken)\r\n at
Bridges.Sectors.Infrastructure.Repositories.SectorRepository.GetSectorById(Guid
sectorId) in
C:\\Users\\StVa\\source\\repos\\bridges\\Sector\\Bridges.Sectors.Infrastructure\\Repositories\\SectorRepository.cs:line
46\r\n at Bridges.Sectors.API.Services.SectorService.GetSector(Guid
sectorId) in C:\\Users\\StVa\\source\\repos\\bridges\\Sector\\Bridges.Sectors.API\\Services\\SectorService.cs:line
26\r\n at
Bridges.Sectors.API.Schema.Queries.SectorQuery.GetSector(ISectorService
sectorService, Guid sectorId) in C:\\Users\\StVa\\source\\repos\\bridges\\Sector\\Bridges.Sectors.API\\Schema\\Queries\\SectorQuery.cs:line
27\r\n at
HotChocolate.Resolvers.Expressions.ExpressionHelper.AwaitTaskHelper[T](Task`1
task)\r\n at
HotChocolate.Types.FieldMiddlewareCompiler.<>c__DisplayClass3_0.<<CreateResolverMiddleware>b__0>d.MoveNext()\r\n---
End of stack trace from previous location ---\r\n at
HotChocolate.Execution.Processing.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken
cancellationToken)\r\n at HotChocolate.Execution.Processing.ResolverTask.TryExecuteAsync(CancellationToken
cancellationToken)",
Luckily the creators of HotChocolate got your back and created a HotChocolate.Data.EntityFramework nuget package. This package allows you to create a pool of DbContexts and use these in your resolvers.
First register a DbContext pool:
And then we can update our code to use a DbContext instance from this pool:
More information about this feature here:https://chillicream.com/docs/hotchocolate/integrations/entity-framework