我正在尝试获取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的实例
答案 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)
只需添加到@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
的通用方法:
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();