ASP Core Web APIでEF Coreを使用してDBを最新の移行に移行することはできますか?これはコマンドラインから実行できますが、プログラムで実行したいのですが。
更新
Janshair Khanからの回答に基づいて、このヘルパークラスを思いつきました。
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using MyWebApi.Models;
namespace MyWebApi
{
public static class DataSeeder
{
public static void SeedData(this IApplicationBuilder app)
{
var context = app.ApplicationServices.GetService<MyContext>();
if (!context.Database.EnsureCreated())
context.Database.Migrate();
}
}
}
次のようにStartup.cs
のConfigure
メソッドからこれを呼び出すことができます:
app.SeedData();
使用できます
db.Database.EnsureCreated();
現在のモデルでデータベースを最新の状態に保つために。移行を有効にする場合(後続の移行が疑われる場合)、使用します
db.Database.Migrate();
その後の移行を時間をかけて配置します。
db.Database.EnsureCreated()
の呼び出しに関するドキュメントからのメモ:
このAPIは、データベースの作成に移行を使用しないことに注意してください。また、作成されたデータベースは、移行を使用して後で更新することはできません。リレーショナルデータベースを対象とし、移行を使用している場合は、DbContext.Database.Migrate()メソッドを使用して、データベースが作成され、すべての移行が適用されることを確認できます。
単にdb.Database.Migrate()
を呼び出したい場合があります。
上記の宣言で見つかったソースからのコメント here 。
以下のコードを使用して移行を実行します
public async void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<YourContext`enter code here`>();
context.Database.Migrate();
}
}
@steamrollaの回答に基づいて、次の改善を提案します。
public static class EnsureMigration
{
public static void EnsureMigrationOfContext<T>(this IApplicationBuilder app) where T:DbContext
{
var context = app.ApplicationServices.GetService<T>();
context.Database.Migrate();
}
}
これにより、異なるコンテキストの移行を保証することもできます。 IDデータベースがある場合。
使用法:
app.EnsureMigrationOfContext<context>();
ここでの以前の回答と bailando bailando's answer on " Database.EnsureCreatedとDatabase.Migrateを呼び出す方法と場所)に基づいて、EF Core 2.1.2とSQL Serverを使用してプログラムで移行するために、 ? ":
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
namespace MyApp
{
public class Startup
{
// ... (only relevant code included) ...
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyAppContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MyAppContext")));
// ...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
using (var serviceScope = app.ApplicationServices.CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<MyAppContext>();
context.Database.Migrate();
}
// ...
}
}
}
このコードを使用するプロジェクトは Githubで入手可能 です。
Chintan310の答えに基づいて、ここにデータベースの移行方法を示します。これにより、データベース関連のタスクをProgram.cs
:
public static void Main(string[] args)
{
var Host = BuildWebHost(args);
using (var scope = Host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetService<AppDbContext>();
context.Database.Migrate();
var seeder = scope.ServiceProvider.GetService<AppSeeder>();
seeder.Seed().Wait();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
Host.Run();
}
private static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
これは、拡張メソッドを作成した以前の回答に対するわずかな修正です。書き込まれたとおりにスローされるエラーを修正します。
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace MyApp.Extensions
{
public static class IApplicationBuilderExtensions
{
public static void SyncMigrations<T>(this IApplicationBuilder app) where T : DbContext
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<DbContext>();
context.Database.Migrate();
}
}
}
}