繁体   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