You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:47:14