如何在已包含这些更改的新数据库上跳过以前的ef迁移?

时间:2012-07-20 11:32:03

标签: entity-framework entity-framework-4 ef-migrations

我遇到问题的情况如下:

  1. 使用EF 4.1创建的Code First模型和生成的相应数据库
  2. EF升级到4.3.1并添加了迁移(使用IgnoreChanges因为没有模型更改)以开始使用迁移(创建了__MigrtionHistory表并删除了EdmMetadata) - 让我们称之为'InitialMigration'
  3. 模型已更改,例如添加了新属性,并生成了添加相应列的迁移(让我们将其称为'NewPropertyMigration')然后应用于Dev数据库(使用我们的Migrate To Latest初始化策略版本)
  4. 当代码升级为生产时,数据库会按预期更新新列
  5. 然后,当在Dev中创建一个全新的数据库,并且因为它基于最新的模型,它将在创建后立即包含新列,但是当初始化策略运行时,它仍然会发现'InitialMigration'和'NewPropertyMigration'为等待,但它们都失败了,因为EdmMetadata不存在,所以没有什么可以删除,新列已经存在,所以无法添加
  6. 当我在这个新数据库上检查__MigrationHistory表时,它只包含'InitialCreate'条目,这样就可以解释为什么其他两个迁移被认为是挂起的。但我无法看到它们如何在未应用的情况下进入此表,同时它们并不真正需要应用,因为数据库已经包含它们所涵盖的任何更改。 我错过了什么?

    我只想补充一点,似乎有点怀疑'InitialCreate'中的Model列与'NewPropertyMigration'中的Model列不同,即使它们代表相同的模型。这可能是原因吗?

    更新: 这是我用来创建新数据库并同时自动应用任何迁移的代码

    public class MigratePaymentsToLatestVersion<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext
    {
    public void InitializeDatabase(TContext context)
    {
        // Create a brand new database if it doesn't exist but still apply any pending migrations
        context.Database.CreateIfNotExists();
        var migrator = new DbMigrator(configuration);
        migrator.Update();
    }
    }
    

    更新2:显示相同问题的更简单方案

    在进一步研究这个问题时,我已经能够在下面描述的更简单的场景中重现这种行为:

    1. 创建简单的模型和上下文
    2. 在测试应用程序中添加一个实体 - 自动创建所有默认设置数据库并添加对象
    3. 启用迁移 - 生成“InitialCreate”迁移
    4. Update-Database - 命令不返回待处理的迁移,因为'InitialCreation'已经在__MigrationHistory
    5. 删除数据库并重新运行测试应用程序 - 再次自动重新创建数据库
    6. 此时我无法添加任何其他迁移或运行update-database,因为“InitialCreation”迁移被视为待处理但由于所有实体都已存在而无法应用

1 个答案:

答案 0 :(得分:2)

我现在已整理好了。我失踪的关键点似乎与你从4.1移动到4.3的方式有关。我一直在关注ef-4-3-migrations-and-existing-database的步骤。似乎更有效的是SO问题how-to-use-migrations-on-an-existing-db中描述的程序。 如果你比较它们,你会看到一个人在你第一次迁移时依赖-IgnoreChanges(称为'InitialMigration'),而另一个创建一个完整的'InitialCreate'迁移,其中包含你在那个时间点的整个模型。后一种方法的两个重要后果是: - 创建全新数据库时InitialCreate迁移(包含模型的完整定义)用于创建数据库而不是“其他代码”(不确切但是猜测这是未启用迁移时所需的部分)根据模型生成数据库 - 使用最新模型创建新数据库,并在__MigrationHistory中列出所有迁移

因此,使用InitialCreate方法,我可以将迁移应用于现有数据库(对于他们而言,只是跳过了InitialCreate,因为历史记录中的条目是作为程序的一部分手动添加的),同时我能够创建品牌新数据库并向其添加新迁移,而不会出现模型和数据库不同步的错误。

我希望能帮助像我一样遵循第一道程序的人。