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

EF7内存数据库测试使用Interceptor遇报错,求解决方案

解决EF7中ISingletonInterceptor注册报错的问题

错误核心原因

当你通过UseInternalServiceProvider指定自定义服务提供者时,EF不会自动构建内部服务容器,因此所有ISingletonInterceptor类型的拦截器必须提前注册到你自定义的服务提供者中,且要确保拦截器与DbContext使用同一个服务容器,不能通过AddInterceptors直接实例化添加。

正确解决方案

方案1:移除自定义服务提供者(测试场景推荐)

如果不需要自定义服务提供者,直接让EF管理服务容器,拦截器的添加会更简洁:

public void Register(IServiceCollection services)
{
    services.AddDbContext<TDbContext>(options => 
        options.UseInMemoryDatabase(_inMemoryDbIdentifier.DatabaseName, _inMemoryDbIdentifier.InMemoryDatabaseRoot)
               .AddInterceptors(new MaterializationInterceptor()));
}

或者保留OnConfiguring中的代码,同时移除UseInternalServiceProvider调用:

public void Register(IServiceCollection services)
{
    services.AddDbContext<TDbContext>(options => 
        options.UseInMemoryDatabase(_inMemoryDbIdentifier.DatabaseName, _inMemoryDbIdentifier.InMemoryDatabaseRoot));
}

方案2:使用自定义服务提供者时正确注册拦截器

若必须使用自定义服务提供者,需将拦截器与EF相关服务注册到同一个服务集合中,再构建提供者:

public void Register(IServiceCollection services)
{
    // 向当前服务集合添加EF内存数据库和单例拦截器
    services.AddEntityFrameworkInMemoryDatabase()
            .AddSingleton<ISingletonInterceptor, MaterializationInterceptor>();

    var serviceProvider = services.BuildServiceProvider();

    services.AddDbContext<TDbContext>(options => 
    {
        options.UseInMemoryDatabase(_inMemoryDbIdentifier.DatabaseName, _inMemoryDbIdentifier.InMemoryDatabaseRoot);
        options.UseInternalServiceProvider(serviceProvider);
    });
}

关键注意事项

  • ISingletonInterceptor类型的拦截器必须注册为单例(Singleton),EF会在服务容器中查找单例类型的拦截器实例。
  • 禁止创建独立的ServiceCollection构建provider,必须与DbContext所在的服务集合共用同一个容器,否则EF无法找到已注册的拦截器。

内容的提问来源于stack exchange,提问作者Zabaa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 05:52:34