.NET 8升级至.NET 9后无法解析EF Core作用域服务问题求助
.NET 9升级后EF Core依赖注入错误排查与解决
错误信息
运行升级到.NET 9的应用时出现以下错误:
Cannot resolve scoped service 'System.Collections.Generic.IEnumerable`1[Microsoft.EntityFrameworkCore.Infrastructure.IDbContextOptionsConfiguration`1[TestEFCore9Worker.Context.ExampleDbContext]]' from root provider.

上下文代码
Program.cs 服务注册代码
var builder = Host.CreateApplicationBuilder(args); builder.Services.AddHostedService<Worker>(); builder.Services.AddDbContextFactory<ExampleDbContext>(options => { options.UseSqlServer(builder.Configuration.GetConnectionString("DbConnectionString")); }); builder.Services.AddDbContext<ExampleDbContext>(options => { options.UseSqlServer(builder.Configuration.GetConnectionString("DbConnectionString")); }); var host = builder.Build(); host.Run();
ExampleDbContext.cs 实现代码
public class ExampleDbContext : DbContext { public ExampleDbContext(DbContextOptions options) : base(options) { } public required virtual DbSet<ExampleModel> Examples { get; set; } }
Worker.cs 后台服务代码
public class Worker : BackgroundService { private readonly ILogger<Worker> _logger; private readonly IServiceScopeFactory _serviceScopeFactory; public Worker(ILogger<Worker> logger, IServiceScopeFactory serviceScopeFactory) { _logger = logger; _serviceScopeFactory = serviceScopeFactory; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); } using (IServiceScope serviceScope = _serviceScopeFactory.CreateScope()) { var dbContextFactory = serviceScope.ServiceProvider.GetRequiredService<IDbContextFactory<ExampleDbContext>>(); using var dbContext = dbContextFactory.CreateDbContext(); var exampleModel = new ExampleModel { Name = Guid.NewGuid().ToString() }; dbContext.Examples.Add(exampleModel); dbContext.SaveChanges(); } await Task.Delay(1000, stoppingToken); } } }
问题更新
移除Program.cs中的AddDbContext注册后,错误不再出现,但无法理解为何.NET 8中同时使用AddDbContext和AddDbContextFactory没有问题。
原因分析
.NET 9中EF Core对DbContext与DbContextFactory的注册逻辑做了调整:
- 同时调用
AddDbContext和AddDbContextFactory时,EF Core内部注册的IDbContextOptionsConfiguration<ExampleDbContext>服务生命周期为Scoped - 当从根服务提供者解析DbContextFactory相关服务时,尝试获取Scoped服务就会触发这个错误
- .NET 8中EF Core的注册逻辑未引入这个冲突,因此同时注册两者可以正常运行
解决方案
方案一:移除冗余的DbContext注册
由于Worker中已经通过IDbContextFactory<ExampleDbContext>获取DbContext,无需直接注册DbContext。修改Program.cs,删除AddDbContext的代码:
var builder = Host.CreateApplicationBuilder(args); builder.Services.AddHostedService<Worker>(); // 仅保留工厂注册 builder.Services.AddDbContextFactory<ExampleDbContext>(options => { options.UseSqlServer(builder.Configuration.GetConnectionString("DbConnectionString")); }); var host = builder.Build(); host.Run();
方案二:统一配置并调整构造函数(如需保留两种注册)
- 修改DbContext的构造函数为泛型版本:
public class ExampleDbContext : DbContext { public ExampleDbContext(DbContextOptions<ExampleDbContext> options) : base(options) { } public required virtual DbSet<ExampleModel> Examples { get; set; } }
- 统一DbContext的配置逻辑,避免重复配置:
var builder = Host.CreateApplicationBuilder(args); builder.Services.AddHostedService<Worker>(); // 先配置DbContextOptions Action<DbContextOptionsBuilder> dbOptions = options => options.UseSqlServer(builder.Configuration.GetConnectionString("DbConnectionString")); builder.Services.AddDbContextFactory<ExampleDbContext>(dbOptions); builder.Services.AddDbContext<ExampleDbContext>(dbOptions); var host = builder.Build(); host.Run();
内容的提问来源于stack exchange,提问作者ThangLe
相关产品推荐
相关产品推荐

