我最近将项目从 .NET 8 升级到 .NET 9,在运行应用程序时遇到以下错误:
Cannot resolve scoped service 'System.Collections.Generic.IEnumerable`1[Microsoft.EntityFrameworkCore.Infrastructure.IDbContextOptionsConfiguration`1[TestEFCore9Worker.Context.ExampleDbContext]]' from root provider.
背景: 我使用 EF Core 进行数据库访问。我的
ExampleDbContext
使用 ServiceCollection
中的以下配置在 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的构造函数。文件
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);
}
}
}
应用程序在 .NET 8 中运行良好,但升级到 .NET 9 后,开始出现此错误。我怀疑这可能与依赖注入或 EF Core 配置的更改有关。有人可以帮助找出根本原因并提出解决方案吗?
更新:我已经编辑了问题以包含下面@Guru Stron 提到的示例。我注意到,如果我删除 Program.cs 中的 AddDbContext,该错误就不再发生。但是,我不明白为什么,就像在 .NET 8 中一样,我使用两者都没有任何问题。
我能够重现这个问题,但实际上并不重要,问题是
AddDbContextFactory
实际上注册了上下文本身,不需要调用AddDbContext
(尽管AddDbContextFactory
不检查是否存在ctor 与选项),所以只需删除调用:
builder.Services.AddHostedService<Worker>();
builder.Services.AddDbContextFactory<ExampleDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DbConnectionString"));
});
var host = builder.Build();
此外,由于您是手动创建范围,因此通常不需要在提供的代码中使用工厂,只需解析上下文本身:
using (IServiceScope serviceScope = _serviceScopeFactory.CreateScope())
{
var dbContext = serviceScope.ServiceProvider.GetRequiredService<ExampleDbContext>();
var exampleModel = new ExampleModel { Name = Guid.NewGuid().ToString() };
dbContext.Examples.Add(exampleModel);
dbContext.SaveChanges();
}