ASP.NET Core 2 +获取db上下文的实例

时间:2017-08-25 15:41:00

标签: asp.net-core entity-framework-core

我正在尝试获取DbContext的一个实例(所以我可以在启动它时做一些额外的工作),在尝试在Configure方法中获取实例时出现以下错误:

System.InvalidOperationException:'无法解析作用域服务' MyApp.Data.MyDbContext'来自root provider。'

public void ConfigureServices(IServiceCollection services)
{
 services.AddDbContext<MyDbContext>(
                options => options.UseSqlServer(Configuration.GetConnectionString("MyDbContext")));
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

    var dbContext = app.ApplicationServices.GetService(typeof(MyDbContext)) as MyDbContext;
}

我可以通过控制器等访问DbContext的实例

2 个答案:

答案 0 :(得分:27)

Paul Hiles评论是正确的,但该方法在.NET Core 1.0中效果更好。

在ASP.NET Core 2.0中,在Startup.cs中运行任何数据库设置通常是个坏主意。这是因为如果您从CLI或Visual Studio运行任何迁移,它将运行所有Startup.cs并尝试运行您的配置,这将失败。当然,如果你不使用Entity-Framework,那么这不是一个问题,但它仍然不是2.0中的推荐方法。现在建议在Program.cs中执行此操作。

例如,您可以创建IWebHost的扩展方法,该方法将运行您需要的任何设置。

public static IWebHost MigrateDatabase(this IWebHost webHost)
{
    var serviceScopeFactory = (IServiceScopeFactory)webHost.Services.GetService(typeof(IServiceScopeFactory));

    using (var scope = serviceScopeFactory.CreateScope())
    {
        var services = scope.ServiceProvider;
        var dbContext = services.GetRequiredService<YourDbContext>();

        dbContext.Database.Migrate();
    }

    return webHost;
}

然后在Program.cs中,您可以在运行之前调用该方法。

public static void Main(string[] args)
{
    BuildWebHost(args)
        .MigrateDatabase()
        .Run();
}

答案 1 :(得分:1)

Core 2.1及更高版本的更新

只需添加到@Travis Boatman的出色答案中,首选的Main方法语法就具有changed slightly from Core 2.1 onwards,而默认的Main方法现在具有CreateWebHostBuilder而不是BuildWebHost

修改后的代码调用扩展方法,如下所示。

NB:这里的顺序很重要,Build方法返回一个WebHost,这是扩展方法正在扩展的内容,因此您需要在Build()之后调用migration方法,然后Run()之前):

public static void Main(string[] args)
{
    CreateWebHostBuilder(args)
        .Build()
        .MigrateDatabase()
        .Run();
}

迁移多个DbContext

我们的项目中有多个DbContext,因此我将扩展方法更改为可以使用任何类型的DbContext的通用方法:

public static IWebHost MigrateDatabase<T>(this IWebHost webHost) where T:DbContext
{
    var serviceScopeFactory = (IServiceScopeFactory)webHost
        .Services.GetService(typeof(IServiceScopeFactory));

    using (var scope = serviceScopeFactory.CreateScope())
    {
        var services = scope.ServiceProvider;

        var dbContext = services.GetRequiredService<T>();
        dbContext.Database.Migrate();
    }

    return webHost;
}

然后您可以将调用链接起来以迁移不同的上下文:

CreateWebHostBuilder(args)
    .Build()
    .MigrateDatabase<ApiAuthDbContext>()
    .MigrateDatabase<MainDbContext>()
    .MigrateDatabase<SomeOtherDbContext>()
    .Run();