.NET 5 Worker服务DbContext未配置数据库提供程序如何修复
问题根因
你直接调用无参构造函数创建ContainerContext实例时,EF Core没有拿到任何数据库配置信息,不知道要使用SqlServer提供器,因此抛出该异常。你在Program中通过AddDbContext注册的配置仅对依赖注入容器创建的DbContext实例生效,手动new的实例无法自动获取该配置。
解决方案
方案1(推荐):通过依赖注入获取DbContext实例
你已经完成了DbContext的服务注册,无需手动new实例,利用.NET自带的依赖注入机制即可自动获取配置好的DbContext。
注意:BackgroundService派生的Worker类是单例生命周期,而默认注册的DbContext是作用域(Scoped)生命周期,不能直接注入到Worker的构造函数中,需要通过IServiceScopeFactory手动创建作用域获取实例。
修改Worker.cs代码:
public class Worker : BackgroundService { private readonly ILogger<Worker> _logger; private readonly IServiceScopeFactory _scopeFactory; // 构造函数注入IServiceScopeFactory public Worker(ILogger<Worker> logger, IServiceScopeFactory scopeFactory) { _logger = logger; _scopeFactory = scopeFactory; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { // 创建作用域,从作用域服务提供器获取ContainerContext using var scope = _scopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService<ContainerContext>(); var test1 = context.MYTABLE.ToList(); await Task.Delay(300, stoppingToken); } } }
该方案符合.NET开发规范,不需要手动维护DbContext的配置、生命周期,框架会自动处理资源释放。
方案2:重写DbContext的OnConfiguring方法(可选,适合不需要DI的场景)
如果要保留直接new无参构造函数的用法,可以在ContainerContext中重写OnConfiguring方法,在方法内部配置数据库提供器和连接字符串。
修改ContainerContext.cs代码:
public partial class ContainerContext : DbContext { public ContainerContext() { } public ContainerContext(DbContextOptions<ContainerContext> options):base(options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // 如果还没有配置选项,就加载配置设置SqlServer提供器 if (!optionsBuilder.IsConfigured) { IConfiguration config = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .Build(); optionsBuilder.UseSqlServer(config.GetConnectionString("Container")); } } }
修改后你原来的section1代码就可以正常运行,但该方案耦合了配置读取逻辑,灵活度不如依赖注入方案。
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

