如何从头开始重新创建迁移

时间:2013-07-18 17:37:28

标签: entity-framework ef-migrations

我最近从EF6 alpha 1-3升级到EF6 beta 1. This意味着我必须重新创建使用alpha版本创建的所有迁移。

所以我尝试回滚到使用EF5创建的迁移。但我点击错误在表上引入FOREIGN KEY约束可能会导致循环或多个级联路径。我认为这是因为当我修复完全相同问题的迁移时,我忽略了修复Down迁移。 (之前应该阅读this

无论如何,我试图重置所有迁移,而不是尝试修复它 - 如here所述。我删除了数据库中的迁移表和所有迁移.cs文件,然后是包管理器Enable-Migrations -EnableAutomaticMigrations -ForceAdd-Migration Initial

当我尝试使用现有的数据库初始化程序(自动迁移为false)运行我的应用程序时,它失败了,因为它试图创建已存在的表。所以我将初始化程序更改为Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>())

这次我在表上引入了引入FOREIGN KEY约束可能会在初始化期间再次导致循环或多个级联路径问题

所以我在迁移文件中将所有cascadeDelete: true更改为cascadeDelete: false

但我仍然得到同样的错误!

更新1 我删除了迁移文件中除了创建1个表之外的所有内容,但是我收到了同样的错误。某处必须有某种缓存,或者它正在拾取一个我不知道的文件,或者它正在后台生成自己的迁移

更新2 我认为在使用DropCreateDatabaseAlways时,EF必须始终生成迁移,并且在迁移文件中将cascadeDelete更改为false是错误的地方它。它应该在FluentAPI中完成。所以我将此行modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();添加到onmodelcreating中。我还删除了初始迁移文件。然后我运行了应用程序,它正确生成了一个数据库。我以为我已经破解了但是......

我更改了初始化以使用我原来的配置文件:

internal sealed class Configuration : DbMigrationsConfiguration<SID2013Context>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
            AutomaticMigrationDataLossAllowed = true;
        }

         protected override void Seed(etc..
}

然后我运行了应用程序并报告模型已更改。所以我做了Add-Migration Update-Database和创建数据库的迁移文件。

现在的问题是,当我运行应用程序时,它会尝试运行另一个更新(即使AutomaticMigrationsEnabled = false)。我得到了“数据库中已经有一个名为'xxx'的对象”问题了。迁移表中有一个与配置文件名称不匹配的条目。

2 个答案:

答案 0 :(得分:2)

如果您想使用现有数据库开始“代码优先迁移”工作,您可以执行以下操作:

  1. 我运行了添加迁移“InitialMigrations”。
  2. 它探索现有数据库并使其成为迁移步骤。
  3. 暂时删除“InitialMigrations”步骤的内容:

    public partial class InitialMigrations : DbMigration {
        public override void Up()
        {
            //...
            //...
        }
    
        public override void Down()
        {
            //...
            //...
        } 
    }
    
  4. 我运行update-database

  5. 这将在表__MigrationHistory。
  6. 中创建相应的条目
  7. 恢复“InitialMigration”的内容在空数据库中正常工作。
  8. 就是这样。

    更新:初始化程序

    据我了解,'DropCreateDatabaseAlways'总是删除并创建数据库。这只能用于第一次安装。如果您有可用的安装启动板,则会清除所有数据。这就是我危险的原因。

    我基于这篇文章:coding.abel.nu/2012/03 / ...我自己的初始化程序我正在使用。我会写的。

    种子是明确执行的,所以这种方法会产生相同的结果,但即使你没有运行安装,但是运行升级它也能正常工作。

    public partial class MyEntities : DbContext
    {
       static MyEntities()
       { 
           Database.SetInitializer<MyEntities>(new ValidateDatabase<MyEntities>());
       }
    }
    /// <summary>
    /// http://coding.abel.nu/2012/03/prevent-ef-migrations-from-creating-or-changing-the-database/
    /// </summary>
    /// <typeparam name="TContext"></typeparam>
    public class ValidateDatabase<TContext> : IDatabaseInitializer<TContext>
      where TContext : DbContext
    {
        public void InitializeDatabase(TContext context)
        {
            if (!context.Database.Exists())
            {
                throw new ConfigurationErrorsException(
                  "Database does not exist");
            }
            else
            {
                if (!context.Database.CompatibleWithModel(true))
                {
                    //from:
                    //http://stackoverflow.com/questions/11611322/ef-4-3-code-first-migrations-seed-per-migration
                    var cfg = new Migrations.Configuration();
                    var migrator = new DbMigrator(cfg);
    
                    ///Last in the db, (first, the reverse order)
                    var dbLast = migrator.GetDatabaseMigrations().FirstOrDefault();
                    ///last in the app
                    var appLast = migrator.GetLocalMigrations().LastOrDefault();
                    ///what is missing
                    var pendings = string.Join(", ", migrator.GetPendingMigrations());
                    throw new InvalidOperationException(
                      string.Format("The database ({0}) is not compatible with the entity model ({1}). Pending migrations: {2}",
                        dbLast, appLast, pendings));
                }
            }
        }
    }
    

    更新:设置

    安装我正在使用这样的东西:

    http://coding.abel.nu/2012/04/update-database-msi-custom-action/

答案 1 :(得分:0)

我最后通过手动删除数据库然后使用原始MigrateDatabaseToLatestVersion初始化程序运行应用程序来解决此问题。我没有意识到这会创建数据库,如果它不存在,并且不需要使用DropCreateDatabaseAlways初始化程序然后更改为MigrateDatabaseToLatestVersion