web-dev-qa-db-ja.com

ASP-起動時にコア移行EF Core SQL DB

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.csConfigureメソッドからこれを呼び出すことができます:

app.SeedData();
46
Zeus82

使用できます

db.Database.EnsureCreated();

現在のモデルでデータベースを最新の状態に保つために。移行を有効にする場合(後続の移行が疑われる場合)、使用します

db.Database.Migrate();

その後の移行を時間をかけて配置します。

27
Janshair Khan

db.Database.EnsureCreated()の呼び出しに関するドキュメントからのメモ:

このAPIは、データベースの作成に移行を使用しないことに注意してください。また、作成されたデータベースは、移行を使用して後で更新することはできません。リレーショナルデータベースを対象とし、移行を使用している場合は、DbContext.Database.Migrate()メソッドを使用して、データベースが作成され、すべての移行が適用されることを確認できます。

単にdb.Database.Migrate()を呼び出したい場合があります。

上記の宣言で見つかったソースからのコメント here

37
steamrolla

以下のコードを使用して移行を実行します

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();
    }
}
14
chintan310

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

ここでの以前の回答と 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で入手可能 です。

1
Lauri Harpf

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

これは、拡張メソッドを作成した以前の回答に対するわずかな修正です。書き込まれたとおりにスローされるエラーを修正します。

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();
            }
        }
    }
}
0
Dblock247