gpt4 book ai didi

c# - EF Core - 对 Context 的多个异步调用导致错误

转载 作者:行者123 更新时间:2023-12-03 08:02:52 24 4
gpt4 key购买 nike

这是我的情况。我创建了一个 blazor 服务器应用程序来管理产品库存。我有多个存储库,它们使用相同的数据库上下文来搜索或查询数据库实体。

在我的库存页面中,我有一个异步调用,它根据搜索参数搜索所有用户的库存产品(每次用户在搜索输入字段中输入字母时都会调用搜索)。当在短时间内多次调用搜索查询时,我似乎收到此错误:

“在上一个操作完成之前,已在此上下文实例上启动了第二个操作”

这是我的数据库配置:

 builder.Services.AddDbContext<NimaDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("NimaDbConnection"));
});

DI:

services.AddScoped<ISearcheableInventoryProductRepository<UserInventoryProductMapping>, UserInventoryProductMappingRepository>();

services.AddScoped<IUserInventoryProductMappingService, UserInventoryProductMappingService>();

这是来自 Razor 组件的调用:

private async Task SearchUserInventoryProducts(int pageNumber)
{
PaginationFilter.PageNumber = pageNumber;

UserInventoryProductMappings = await _userInventoryProductMappingService
.SearchByUserInventoryId(PaginationFilter, UserInventory.UserInventoryId);
}

我的服务:

public async Task<PagedResponse<UserInventoryProductMappingDto>> SearchByUserInventoryId(PaginationFilter paginationFilter, int userInventoryId)
{
var result = await _repository.SearchByUserInventoryId(_mapper.Map<PaginationQuery>(paginationFilter), userInventoryId);

return _mapper.Map<PagedResponse<UserInventoryProductMappingDto>>(result);
}

我的存储库:

 public async Task<PagedResponse<UserInventoryProductMapping>> 

SearchByUserInventoryId(PaginationQuery query, int userInventoryId)
{
try
{
var defaultQuery = GetDefaultQuery().Where(x => x.UserInventoryId == userInventoryId);

if (query.SearchString != null)
{
defaultQuery = defaultQuery.Where(x => x.Product.NameLabel.LabelDescriptions.Any(x => x.Description.Contains(query.SearchString)));
}

if (query.SortBy != null && query.SortById != null)
{
switch (query.SortBy)
{
case "productCategory":
defaultQuery = defaultQuery.Where(x => x.Product.ProductCategoryId == query.SortById);
break;
case "productSubCategory":
defaultQuery = defaultQuery.Where(x => x.Product.ProductSubCategoryId == query.SortById);
break;
}
}

int count = defaultQuery.Count();
return new PagedResponse<UserInventoryProductMapping>
{
Data = await defaultQuery
.Skip((query.PageNumber - 1) * query.PageSize)
.Take(query.PageSize)
.ToListAsync(),
PageNumber = query.PageNumber,
PageSize = query.PageSize,
TotalPages = (int)Math.Ceiling(count / (double)query.PageSize)

};
}
catch (Exception e)
{
_logger.LogError(e, e.Message);

throw;
}
}

我已确保我的询问均已得到妥善处理。我还尝试将数据库上下文切换为 transient 服务生命周期,但没有成功。我的服务、存储库和上下文正在使用范围服务生命周期。在这种情况下我做错了什么?感谢您的帮助。

最佳答案

我建议您查看 Blazor 的服务生命周期文档:

https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/dependency-injection?view=aspnetcore-6.0#service-lifetime

在 Blazor 中,作用域服务大多在每个用户 session 中实例化一次。它基本上是每个用户的单例。

将 DBContext 更改为 transient 不会执行任何操作,因为存储库仍处于限定范围内,因此每个 session 仍仅注入(inject)一次 DBContext。

您将有多种选择,我认为最简单的是使用 DBContextFactory 或 PooledDBContextFactory 并为每个工作单元实例化一次新上下文。

看这里: https://learn.microsoft.com/en-us/ef/core/dbcontext-configuration/#using-a-dbcontext-factory-eg-for-blazor

关于c# - EF Core - 对 Context 的多个异步调用导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73474865/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com