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;
}
コントローラなどを介してDbContextのインスタンスに正常にアクセスできます。
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();
}
@ Travis Boatman の優れた答えに追加するために、推奨されるMain
メソッドの構文は Core 2.1以降わずかに変更されました とデフォルトのMain
メソッドにCreateWebHostBuilder
の代わりにBuildWebHost
が追加されました。
拡張メソッドを呼び出すための修正されたコードを以下に示します。
注意:ここでは順序が重要です。Build
メソッドはWebHost
を返します。これは拡張メソッドが拡張しているものです。したがって、Build()
の後にmigrateメソッドを呼び出す必要がありますおよび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();