C# 在gRPC服务实现中获取DbContext的正确方法
各种联机示例显示了将DbContext注入服务构造函数中的gRPC服务:C# 在gRPC服务实现中获取DbContext的正确方法,c#,entity-framework,grpc,C#,Entity Framework,Grpc,各种联机示例显示了将DbContext注入服务构造函数中的gRPC服务: public ImageStorageService(ILogger<ImageStorageService> logger, SqliteDbContext dbContext) { _logger = logger; _dbContext = dbContext; } publicmagestorageservice(ILogger记录器,SqliteDbContext) { _记录器=记
public ImageStorageService(ILogger<ImageStorageService> logger, SqliteDbContext dbContext)
{
_logger = logger;
_dbContext = dbContext;
}
publicmagestorageservice(ILogger记录器,SqliteDbContext)
{
_记录器=记录器;
_dbContext=dbContext;
}
并在所有gRPC实现方法中使用该dbContext。这似乎不对-我对EF和.Net核心web一般来说是新手,但DbContext不是线程安全的,可以同时执行多个gRPC方法,是吗
无论如何,我找到了另一种方法,下面是构造函数和示例api方法实现:
public ImageStorageService(ILogger<ImageStorageService> logger, IServiceScopeFactory serviceScopeFactory)
{
_logger = logger;
_serviceScopeFactory = serviceScopeFactory;
}
public override async Task<GetImageCountReply> GetImageCount(GetImageCountRequest request, ServerCallContext context)
{
using var scope = _serviceScopeFactory.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<SqliteDbContext>();
var count = await dbContext.StoredImages.CountAsync(context.CancellationToken);
return new GetImageCountReply { Count = count };
}
公共图像存储服务(ILogger记录器、IServiceScopeFactory服务范围工厂)
{
_记录器=记录器;
_serviceScopeFactory=serviceScopeFactory;
}
公共重写异步任务GetImageCount(GetImageCountRequest请求,ServerCallContext上下文)
{
使用var scope=_serviceScopeFactory.CreateScope();
var dbContext=scope.ServiceProvider.GetRequiredService();
var count=await dbContext.StoredImages.CountAsync(context.CancellationToken);
返回新的GetImageCountReply{Count=Count};
}
我把事情复杂化了吗?services.AddDbContext使用作用域生存期注入数据库上下文,所以这是必要的,不是吗?我相信没有什么比通常的using(SqliteDbContext dbContext=new SqliteDbContext())形式更好的了。我之所以不在自己的代码中注入DbContext,是因为我保留了为接口而不是具体类(但不是绝对规则)而保留的注入。在您的示例中,当您请求DbContext时,您会指出所需的DbContext类型,那么您为什么还需要额外的齿轮来实例化它呢?这是因为您正在将参数传递给DbContext的构造函数吗?例如,在性能允许的情况下,使用简单注入器可以使用AddDbContextPool之类的内置功能。我认为注射是最好的方法。