I have two properties that are both loading from Entity Framework Core and getting projected into an IQueryable result of the projected type. The context.Service() method doesn't seem to have the DbContextKind argument available to solve the concurrent DbContext access problem that is mentioned in the docs.
Specifically, I get this error: "A second operation was started on this context instance 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."
It only happens if I have both descriptors coded, but doesn't happen if I comment out one. The reason clearly is that the processing of these descriptors is done in parallel and the same instance of DbContext is injected and accessed in parallel.
What should I be doing?
public class UserType : ObjectType<WISEcode.Data.DTOs.GQL.Food> {
public UserType()
{
}
protected override void Configure(IObjectTypeDescriptor<WISEcode.Data.DTOs.GQL.Food> descriptor)
{
descriptor
.Field("foodLists").UseFiltering().UseSorting()
.Resolve(context =>
{
WISEcode.Data.DTOs.GQL.Food food = context.Parent<WISEcode.Data.DTOs.GQL.Food>();
var dbContext = context.Service<ApplicationDbContext>();
var foodLists = dbContext.FoodLists.AsSingleQuery().Where(fl => fl.Foods.Any(f=> f.Id == food.Id)).ProjectToType<WISEcode.Data.DTOs.GQL.FoodList>();
return foodLists;
});
descriptor
.Field("top5GoodFoodExpressions").UseFiltering().UseSorting()
.Resolve(context =>
{
WISEcode.Data.DTOs.GQL.Food food = context.Parent<WISEcode.Data.DTOs.GQL.Food>();
var dbContext = context.Service<ApplicationDbContext>();
var foodExpressions = dbContext.FoodExpressionFoods.AsSingleQuery().Where(fef => fef.FoodId == food.Id && fef.FoodExpression.FoodExpressionSentiment == FoodExpressionSentiment.Good).Select(fef => fef.FoodExpression).OrderBy(fe => fe.FoodExpressionSentimentDisplayOrder);//.Take(5),
return foodExpressions;
});
}
}
Here is code for setup:
builder.Services
.AddGraphQLServer()
.RegisterService<FoodExpressionService>(ServiceKind.Synchronized)
.AddAuthorization()
.AddFiltering()
.AddSorting()
.AddProjections()
.SetPagingOptions(new PagingOptions
{
MaxPageSize = 250
})
.AddType<WISEcode.Api.GQL.Query>()
.AddType<UserType>()
.AddType<FoodGQLType>()
.AddType<UserGQLType>()
.AddType<FoodExpressionGQLType>()
.AddType<FoodExpressionCategoryGQLType>()
.RegisterDbContext<ApplicationDbContext>(DbContextKind.Synchronized);