web-dev-qa-db-ja.com

EntityFramework Coreの自動移行

Asp.netコアプロジェクトのEntity Framework corecode firstに自動移行を実行するコードはありますか?

私は単にMVC4/5でそれを追加することでそれを行います

Database.SetInitializer(new MigrateDatabaseToLatestVersion<AppDbContext, MyProject.Migrations.Configuration>());
public Configuration() {
          AutomaticMigrationsEnabled = true;
        }

これにより、エンティティが変更されたときに時間を節約できます

31

_Startup.cs_でcontext.Database.Migrate()を呼び出すことができます

例えば:

_using (var context = new MyContext(...))
{
    context.Database.Migrate();
}
_
26
Frank Odoom

EFコアはサポートしていませんautomatic migrations。だからあなたは手動でそれをしなければなりません。

機能としての自動移行の観点からは、コードベースの移行がより管理しやすいアプローチであることが経験上示されているため、EF Coreに実装する予定はありません。

詳細はこちらでご覧いただけます: 自動移行を実装しない

25
Sampath

これは、IdentityServer4で行う方法です http://identityserver.io

public void ConfigureServices(IServiceCollection services)
{
    var connectionString = Configuration.GetConnectionString("DefaultConnection");
    var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

    // Add framework services.
    services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(connectionString));
    ...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // this will do the initial DB population
    InitializeDatabase(app);
}

private void InitializeDatabase(IApplicationBuilder app)
{
    using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
    {
        scope.ServiceProvider.GetRequiredService<ApplicationDbContext>().Database.Migrate();
        scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
        ...
    }
}
15
Matt Morgan

EF Coreでは自動移行はサポートされていません。移行するには、手を作成する必要があります。すべての既存の手作りの移行を自動的に適用するには、DbContextに次のコードを追加する必要があります。

public sealed class MyDbContext : DbContext
{
  private static readonly bool[] _migrated = { false };

  public MyDbContext( DbContextOptions<MyDbContext> options ) : base( options )
  {
    if ( !_migrated[0] )
      lock ( _migrated )
        if ( !_migrated[0] )
        {
          Database.Migrate(); // apply all migrations
          _migrated[0] = true;
        }
  }
}

エレガントではありませんが、機能します。

EFCore 2.1の更新:

public class Program
{
    public static void Main(string[] args)
    {
        var Host = CreateWebHostBuilder(args).Build();

        using (var scope = Host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                var context = services.GetRequiredService<MyDbContext>();
                context.Database.Migrate(); // apply all migrations
                SeedData.Initialize(services); // Insert default data
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred seeding the DB.");
            }
        }

        Host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}
13
Mentor

Microsoftのドキュメントに従う

https://docs.Microsoft.com/en-us/aspnet/core/data/ef-mvc/intro

依存性注入を使用している場合は、最初に静的クラスData/DbInitializer.csをセットアップし、次のコードを追加する必要があります。

public static class DbInitializer
{
    public static void Initialize(ApplicationDbContext context)
    {
        context.Database.Migrate();

        // Add Seed Data...
    }
}

シードデータを追加できる場所でもあります。

次に、Program.csファイルに次のコードを追加します

public static void Main(string[] args)
    {
        var Host = BuildWebHost(args);

        using (var scope = Host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;
            try
            {
                var environment = services.GetRequiredService<IHostingEnvironment>();

                if (!environment.IsDevelopment())
                {
                    var context = services.GetRequiredService<ApplicationDbContext>();
                    DbInitializer.Initialize(context);
                }
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred while seeding the database.");
            }
        }

        Host.Run();
    }

私の場合、環境をチェックして、開発中かどうかを確認して、移行/更新を制御できるようにします。ただし、実稼働環境では、継続的な統合のために自動化する必要があります。他の人が述べたように、これはおそらくベストプラクティスではありませんが、小さなプロジェクトではうまく機能します。

3
Amac

作業中の自動移行コードAsp Net Core 2.0.7。

    // startup.cs
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // configure app

        SeedData.Initialize(app.ApplicationServices);
    }       

    // dbInitializer.cs
    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            using (var serviceScope = serviceProvider.CreateScope())
            {
                var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();

                // auto migration
                context.Database.Migrate();

                // Seed the database.
                InitializeUserAndRoles(context);
            }
        }

        private static void InitializeUserAndRoles(ApplicationDbContext context)
        {
            // init user and roles  
        }
    }
2
dev-siberia

DbコンテキストコンストラクターでDatabase.Migrate()を呼び出すことができます。

1
Evgeniy K

私の最善のアドバイスは、自動移行を使用しないことです。移行を手動で追加し、一括移行を避け、手動移行を使用するためのベストプラクティスに従うことを常にお勧めします

自動移行は魔法のツールではありません。また、移行にいくつかの追加変更を追加したい場合があります。手動移行を使用することによってのみ達成できます。

移行を有効にするには、パッケージマネージャーコンソールで「enable-migrations」と入力します

これにより、データベースのアップグレードまたはダウングレードを完全に制御でき、移行を簡単に追跡できます。

パッケージマネージャーコンソールの3つの簡単な手順。

1)移行の追加[移行の名前]

2)変更に対して移行が生成されます。それらを確認し、変更することもできます

3)データベースの更新は、移行が完了しました。

移行の処理が簡単になりました!

0
srini