c# – UseInMemoryDatabase与UseInternalServiceProvider.没有配置数据库提供商

使用EntityFrameworkCore时,我在注入自定义IAsyncQueryProvider时遇到问题.更准确地说,在使用提供的内存数据库功能时,我无法注入提供程序.使用默认提供程序(SqlServer),一切正常.这是我的全球Startup.csprivate voi...

使用EntityFrameworkCore时,我在注入自定义IAsyncQueryProvider时遇到问题.更准确地说,在使用提供的内存数据库功能时,我无法注入提供程序.使用默认提供程序(SqlServer),一切正常.

这是我的全球Startup.cs

private void ConfigureEntityFrameworkWithSecurity(IServiceCollection services)
{
    services
        .AddEntityFramework()
        .AddEntityFrameworkSqlServer()
        .AddScoped<IAsyncQueryProvider, CustomEntityProvider>()
        .AddDbContext<APIContext>((sp, options) =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
                .UseInternalServiceProvider(sp);
        });
}

这完美无缺,我可以在CustomEntityProvider中放置一个断点来验证它是否确实被注入.目前,CustomEntityProvider只是实现IAsyncQueryProvider,并简单地传递请求.其中没有包含逻辑.

当我运行测试时,我将webhost配置为使用不同的启动文件:

public class TestStartup : Startup
{
    public TestStartup(IHostingEnvironment env) : base(env)
    {
    }

    public override void ConfigureServices(IServiceCollection services)
    {
        services
            .AddDbContext<APIContext>((sp, options) =>
            {
                options.UseInMemoryDatabase()
                    .UseInternalServiceProvider(sp);
            });
        base.ConfigureServices(services);
    }
}

使用TestStartup运行测试会产生错误:

System.InvalidOperationException : No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext.

并正确定义了APIContext:

public class APIContext : DbContext
{
    public APIContext(DbContextOptions<APIContext> options)
        : base(options)
    {
    }
    ...
}

从TestStartup中删除UseInternalServiceProvider正常工作 – 但是,我不希望我的测试命中实际的数据库.此外,我希望UseInMemoryDatabase能够自动将依赖项注入服务提供者 – 因为它本身可以很好地工作.

该错误令人困惑,因为内存数据库是我想要使用的提供程序.

解决方法:

不幸的是,解决方案很简单.但是,似乎很少有关于将依赖注入与内存数据库功能一起使用的文档.它似乎是一个或另一个.希望这个问题能够为将来不幸遇到这种情况的人们提供帮助.

我下载了EntityFramework源进行调查,发现调用UseInMemoryDatabase创建了一个扩展名InMemoryOptionsExtension,它本身将添加到服务提供者,即:

public virtual void ApplyServices(IServiceCollection services)
{
    Check.NotNull(services, nameof(services));

    services.AddEntityFrameworkInMemoryDatabase();
}

解决方案就像它看起来一样简单:

public class TestStartup : Startup
{
    public TestStartup(IHostingEnvironment env) : base(env)
    {
    }

    public override void ConfigureServices(IServiceCollection services)
    {
        services
            .AddEntityFrameworkInMemoryDatabase()
            .AddDbContext<APIContext>((sp, options) =>
            {
                options.UseInMemoryDatabase().UseInternalServiceProvider(sp);
            });
        base.ConfigureServices(services);
    }
}

本文标题为:c# – UseInMemoryDatabase与UseInternalServiceProvider.没有配置数据库提供商

基础教程推荐