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
相关产品推荐
相关产品推荐

