无法从DI移除DbContext:ASP.NET Core测试替换上下文报错
解决ASP.NET Core集成测试中替换DbContext为内存数据库的多提供者冲突问题
你遇到的问题是原项目已注册PostgreSQL数据库提供者,测试代码又添加了InMemory提供者,导致容器内存在两个数据库提供者服务,违反了EF Core仅允许注册一个提供者的限制。无需修改Program.cs,只需在CustomWebApplicationFactory中更彻底地清理原有DbContext相关服务即可。
修正后的代码实现
protected override void ConfigureWebHost(IWebHostBuilder builder) { builder.ConfigureServices(services => { // 移除原有的DartsDbContext服务实例 var contextDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DartsDbContext)); if (contextDescriptor != null) { services.Remove(contextDescriptor); } // 精准移除DartsDbContext对应的DbContextOptions配置 var optionsDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<DartsDbContext>)); if (optionsDescriptor != null) { services.Remove(optionsDescriptor); } // 重新注册使用内存数据库的DartsDbContext services.AddDbContext<DartsDbContext>(options => { options.UseInMemoryDatabase("InMemoryDbForTesting"); // 可选配置:禁用延迟加载、开启敏感数据日志(方便测试调试) options.UseLazyLoadingProxies(false); options.EnableSensitiveDataLogging(); }); }); }
原代码失效原因
你之前尝试移除所有DbContextOptions<>泛型服务的方式不够精准,未能彻底清除原项目为DartsDbContext注册的特定DbContextOptions<DartsDbContext>实例,导致PostgreSQL的提供者配置残留,与新添加的InMemory提供者冲突。
极端情况兜底方案
如果上述代码仍报错,可添加以下步骤彻底清除所有数据库提供者服务:
// 在移除DbContextOptions之后添加 using Microsoft.EntityFrameworkCore.Infrastructure; var dbProviderDescriptors = services.Where(d => d.ServiceType == typeof(IDatabaseProvider)).ToArray(); foreach (var descriptor in dbProviderDescriptors) { services.Remove(descriptor); }
该操作会清空所有已注册的数据库提供者,确保仅InMemory提供者被保留。
内容的提问来源于stack exchange,提问作者Shkerbs
相关产品推荐
相关产品推荐

