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

The*_*Guy 19 entity-framework-core asp.net-core

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

System.InvalidOperationException:'无法从根提供程序解析作用域服务'MyApp.Data.MyDbContext'.

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;
}
Run Code Online (Sandbox Code Playgroud)

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

Tra*_*man 31

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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


tom*_*dox 6

Core 2.1 以上的更新

只是为了补充@Travis Boatman的优秀答案,从 Core 2.1 开始,首选Main方法的语法略有变化,默认Main方法现在CreateWebHostBuilder使用BuildWebHost.

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

注意:这里的顺序很重要,该Build方法返回一个WebHost,这是扩展方法正在扩展的,因此您需要在 之后Build()和之前调用 migrate 方法Run()):

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

迁移多个 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;
}
Run Code Online (Sandbox Code Playgroud)

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

CreateWebHostBuilder(args)
    .Build()
    .MigrateDatabase<ApiAuthDbContext>()
    .MigrateDatabase<MainDbContext>()
    .MigrateDatabase<SomeOtherDbContext>()
    .Run();
Run Code Online (Sandbox Code Playgroud)