Eager Loading在BackgroundService中无法正常生效问题求助
问题原因
- 生命周期不匹配:
AddDbContext默认将DbContext注册为Scoped作用域,而BackgroundService属于全局单例服务。直接将Scoped服务注入单例服务,会导致DbContext被提升为单例生命周期,上下文长期不释放会触发跟踪缓存、事务状态异常等问题,进而导致关联加载失效。Web项目中每个请求对应独立Scoped作用域,DbContext生命周期正常,因此关联加载能正常执行。 - 服务容器重复构建:你在
ConfigureServices方法末尾手动调用了BuildServiceProvider(),这会生成独立于Host默认容器的额外服务提供程序,导致服务实例不一致,也是引发数据查询异常的常见原因。 - 同步查询潜在异常:EF Core 5中同步查询在单例DbContext下容易出现状态同步问题,可能影响Include关联加载的正常执行。
解决方案
1. 移除ConfigureServices中多余的BuildServiceProvider调用
修改Program代码如下:
class Program { static async Task Main(string[] args) { using IHost host = CreateHostBuilder(args).Build(); await host.RunAsync(); } static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices((context, services) => { services.AddLogging() .AddDbContext<MyDbContext>(options => options .UseSqlServer(context.Configuration.GetConnectionString("MyConnection"))) .AddHostedService<MyService>(); // 移除多余的BuildServiceProvider调用 }); }
2. 用IServiceScopeFactory创建作用域获取DbContext
不要直接注入DbContext到BackgroundService,改为注入IServiceScopeFactory,每次执行数据库操作时手动创建Scoped作用域获取DbContext实例:
public class MyService : BackgroundService { private readonly IServiceScopeFactory _scopeFactory; public MyService(IServiceScopeFactory scopeFactory) { _scopeFactory = scopeFactory; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // 每次操作创建独立作用域 using var scope = _scopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService<MyDbContext>(); // 使用异步查询 var theBatch = await context.Batches.Include(x => x.Jobs).FirstOrDefaultAsync(stoppingToken); } }
修改完成后重新运行即可正常加载关联的Jobs实体。
内容的提问来源于stack exchange,提问作者mshwf
相关产品推荐
相关产品推荐

