簡體   English   中英

ASP.NET 核心 2 + 獲取數據庫上下文實例

[英]ASP.NET Core 2 + Get instance of db context

我正在嘗試獲取 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;
}

我可以通過 controller 等訪問 DbContext 的實例

Paul Hiles 的評論是正確的,但該方法在 .NET Core 1.0 中效果更好。

在 ASP.NET Core 2.0 中,在Startup.cs運行任何數據庫設置通常是一個壞主意。 這是因為如果您從 CLI 或 Visual Studio 運行任何遷移,它將運行所有Startup.cs並嘗試運行將失敗的配置。 當然,如果你不使用實體框架,那么這不是問題,但它仍然不是 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();
}

Core 2.1 以上的更新

只是為了添加@Travis Boatman的優秀答案,首選的Main方法語法從 Core 2.1 開始略有變化,默認Main方法現在使用CreateWebHostBuilder而不是BuildWebHost

調用擴展方法的修改后的代碼如下所示。

注意:這里的順序很重要, Build方法返回一個WebHost ,這是擴展方法所擴展的,因此您需要在Build()Run()之前調用 migrate 方法):

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();

看到這個問題,他在“更新”部分回答了自己

program.cs中添加CreateWebHostBuilder方法

 .UseDefaultServiceProvider(options => {
     options.ValidateScopes = false;//to use any scoped
     option.validateOnBuild = false;//to use dbContext 
})

完整代碼:

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    Host.CreateWebHostBuilder(args).ConfigureWebHostDefaults(webBuilder =>  
        {
            webBuilder.UseStartup<Startup>().UseDefaultServiceProvider(options =>
            {
                options.ValidateScopes = false;
                option.ValidateOnBuild = false;
            });
        })
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM