【问题标题】:Ignore pending migrations after database recreation重新创建数据库后忽略挂起的迁移
【发布时间】:2012-10-31 09:55:46
【问题描述】:

我们在数据库迁移中使用代码优先 EF 4.3.1。有时我们删除数据库并让 EF 重新创建它,主要用于本地开发目的。

有一个应用挂起迁移的过程,当重新创建数据库时,挂起迁移不是必需的,当 EF 尝试应用它们时会引发错误。

我从字符串中检查迁移日期,如果这是在数据库创建日期之前,那么我手动将其添加到 __migrationHistory 表中并且不应用迁移。

这涵盖了大多数情况,除非有人重新创建数据库、从源代码管理更新并检索数据库创建日期之前的未完成迁移。

我也尝试在 dbMigrator.Update(migration) 方法调用周围使用 try catch,但如果一个迁移失败,则不会应用更多迁移,因为它会记住异常。

有没有人找到解决这个问题的方法?

这是我写的方法:

private static void ApplyMigration<T, TU>()
where T : DbContext, new()
where TU : DbMigrationsConfiguration, new()
{
    var migrationsAlreadyApplied = new List<string>();
    var dbMigrator = new DbMigrator(new TU());

    var creationMigrationId = dbMigrator.GetDatabaseMigrations().Single(m => m.Contains("InitialCreate"));
    var dbDateCreated = DateTime.ParseExact(creationMigrationId.Substring(0, 12), Constants.MigrationDateFormat, CultureInfo.InvariantCulture);

    dbMigrator.GetPendingMigrations().ToList()
                                    .ForEach(migration =>
                                    {
                                        var migrationDate = DateTime.ParseExact(migration.Substring(0, 12), Constants.MigrationDateFormat, CultureInfo.InvariantCulture);

                                        if (migrationDate > dbDateCreated)
                                            dbMigrator.Update(migration);
                                        else
                                            migrationsAlreadyApplied.Add(migration);
                                    });

    using (var dbContext = new T())
    {
        foreach(var migration in migrationsAlreadyApplied)
            dbContext.Database.ExecuteSqlCommand("insert into __MigrationHistory "
                      + "select '" + migration + "', Model, ProductVersion "
                      + "from __MigrationHistory "
                      + "where MigrationId = '" + migration + "'");
    }
}

【问题讨论】:

    标签: c# .net entity-framework ef-code-first entity-framework-migrations


    【解决方案1】:

    我现在已经解决了这个问题。

    在我的 dbContext 初始化程序的种子方法中,我调用了一个手动填充迁移历史记录的方法。然后,您可以使用 ApplyMigrations 方法正常调用迁移。

    public class UserEntitiesContextInitializer : CreateDatabaseIfNotExists<UserEntitiesContext>
    {
        protected override void Seed(UserEntitiesContext context)
        {
            // Update migration history with existing migrations to prevent EF recognising them as pending migrations
            DatabaseAdministration.UpdateMigrationHistory<UserEntitiesContext, UserEntitiesContextConfiguration>();
        }
    }
    
    public static void UpdateMigrationHistory<T, TU>()
            where T : DbContext, new()
            where TU : DbMigrationsConfiguration, new()
        {
            using (var dbContext = new T())
            {
                var dbMigrator = new DbMigrator(new TU());
    
                var creationMigrationId = dbMigrator.GetDatabaseMigrations().Single(m => m.Contains("InitialCreate"));
    
                foreach (var migration in dbMigrator.GetPendingMigrations())
                    dbContext.Database.ExecuteSqlCommand("insert into __MigrationHistory "
                                                            + "select '" + migration + "', Model, ProductVersion "
                                                            + "from __MigrationHistory "
                                                            + "where MigrationId = '" + creationMigrationId + "'");
            }
        }
    
    private static void ApplyMigration<T, TU>()
            where T : DbContext, new()
            where TU : DbMigrationsConfiguration, new()
        {
            var dbMigrator = new DbMigrator(new TU());
    
            if (dbMigrator.GetPendingMigrations().Any())
                dbMigrator.Update(dbMigrator.GetPendingMigrations().Last());
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-27
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-03
      相关资源
      最近更新 更多