Автоматические миграции EntityFramework Core

Есть ли какой-либо код для автоматической миграции в Entity Framework core code first в основном проекте asp.net?

Я делаю это просто в MVC4/5, добавляя

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

Это экономит время, когда сущности изменяются

Ответ 1

Вы можете вызвать context.Database.Migrate() в Startup.cs

например:

using (var context = new MyContext(...))
{
    context.Database.Migrate();
}

Ответ 2

EF core не поддерживает automatic migrations. Поэтому вы должны сделать это вручную.

С точки зрения автоматических миграций как функции мы не планируя внедрить его в EF Core, поскольку опыт показал, что кодовая база миграции - более управляемый подход.

Вы можете прочитать полную историю здесь: Не выполнять автоматические миграции

Ответ 3

Так они делают это в 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();
        ...
    }
}

Ответ 4

Автоматическая миграция не поддерживается в 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>();
}

Ответ 5

После документации 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();
    }

В моем случае я проверяю среду, чтобы убедиться, что я в разработке, поэтому я могу контролировать миграцию/обновления. Однако в производстве я хочу, чтобы они были автоматическими для непрерывной интеграции. Как отмечали другие, это, вероятно, не лучшая практика, но на небольших проектах она отлично работает.

Ответ 6

Мой рабочий код миграции 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  
        }
    }

Ответ 7

Вы можете вызвать Database.Migrate() в конструкторе контекста БД.

Ответ 8

мой лучший совет - не использовать автоматическую миграцию. Всегда лучше добавлять миграции вручную, а также избегать массовой миграции и придерживаться наилучшей практики для ручной миграции.

автоматическая миграция не является волшебным инструментом, и будет несколько случаев, когда вы захотите добавить некоторые дополнительные изменения в перенос. Вы выполняете только с помощью ручной миграции.

Чтобы включить миграцию, введите "enable-migrations" в консоли диспетчера пакетов

Таким образом, вы будете иметь полный контроль над обновлением или понижением базы данных, а также легко отслеживать миграцию.

Всего три простых шага в консоли диспетчера пакетов.

1) add-migrations [некоторое имя для вашей миграции]

2) для изменений создаются миграции, вы их просматриваете, а также можете     внесите в него изменения

3) обновленная база данных теперь завершена.

обработка миграции менее болезненна!