问题 EF - 从AutomaticMigrations迁移到手动迁移


测试各种场景的漫长的一天结束,我不必重新创建生产数据库...

我们从EF开始,在开发过程中没有足够明智地从自动迁移转向命名迁移。现在我正在尝试回放时钟,并创建一个与生产数据库对齐的初始迁移。

  1. 这是否可以将模型与迁移表中的自动迁移对齐?
  2. 我是否应该创建一个空迁移来开始命名迁移?我唯一的问题是如何在新开发人员加入时创建数据库...我可以简单地恢复数据库,然后应用迁移,但这会破坏美丽的EF迁移故事!
  3. 删除生产数据库,创建并编写脚本以重新导入数据(听起来很糟糕)。

另一个皱纹 - 数据库是用EF5创建的,我们现在正在开发EF6。

在此先感谢您的帮助。


11454
2017-11-20 00:43


起源

请问为什么Automated Migrations适合您 - phil soady
IT确实如此,但我希望更多地控制对生产数据库的部署。我对该主题的研究表明,自动迁移根本不是生产应用程序的最佳实践。 - codeputer
可以测试和控制自动迁移。即只在您希望它们运行时触发。不只是因为部署了代码。您还提名允许数据丢失。因此,只有新列或兼容的更改。我仍然明白,当看到升级代码时,人们会感到更舒服。如果你找到答案,我感兴趣。我有同样的情况。 :-) - phil soady


答案:


它应该是可能的:

  1. 删除__MigrationHistory表
  2. 删除项目中的所有迁移
  3. 禁用迁移配置类中的自动迁移
  4. 添加迁移InitialCreate
  5. Update-Database -Script
  6. 执行创建__MigrationHistory表的脚本部分并在其中插入一行
  7. 对任何其他现有数据库重复步骤1和6

我也强烈建议阅读 团队环境中的代码优先迁移


11
2017-11-20 22:59



因为你在EF6上 msdn.microsoft.com/en-us/data/dn481501 - phil soady
Hadnt注意到之前的页面...谢谢 - phil soady
有用的链接,谢谢。 - Dresel
我认为这个答案还不够好。下面的一个更有用,实际上解决了这个问题。 - Kyberias
@Kyberias StackOverflow随着时间的推移而发展。我们的答案两年过去了。 WouterSchut的答案是巧妙地自动化和改进这些步骤。为什么试图抹黑我的答案呢?只需投票支持并继续前进。 - bricelam


如果你不喜欢bricelam答案的第7步。然后继续阅读。

因为从自动迁移升级到手动也可以自动化。而且你不需要像bricelam那样删除migrationhistory表。

在这种情况下,我假设您有一台开发机器和多台其他(开发)机器,其中已存在数据库。

  1. 在您的开发机器上,您将数据库移动到一个安全的位置(保持安全,以测试您的自动升级过程)。 (您可能希望确保您的代码与要升级的所有数据库处于完全相同的状态)。

  2. 删除项目中的任何迁移(您还没有任何迁移)

  3. 禁用迁移配置类中的自动迁移

  4. 添加迁移InitialCreate

  5. 将数据库的备份(副本!)放回原位

  6. 在启动应用程序(或升级应用程序)时,您可以执行以下操作:

        using (var db = new YourDatabaseContext())
        {
            InitialCreate.SkipInitialCreate = db.Database.Exists();
        }
    

在您的InitialCreate中添加如下内容:

    public static bool SkipInitialCreate = false;

    public override void Up()
    {
        // Skip initial create
        if (SkipInitialCreate)
            return;

这假定如果存在数据库,则其结构与您在开发机器上的结构相同。当然,这可能比对你来说更复杂。要获得更多控制,您可以检查配置的DbMigrator对象,并跳过多个迁移。 (如果你能在DbMigrator中查询模型的哈希值,那会很好...)

  1. 在步骤4中的代码之后添加如下内容:

        var configuration = new YourDatabaseConfiguration();
        var migrator = new DbMigrator(configuration);
        migrator.Update();
    
  2. 在您的开发机器上启动您的应用程序以测试升级。您的历史记录表应具有自动迁移记录和初始创建记录。

  3. 如果一切顺利,您应该能够在db已经存在的机器上简单地部署和运行应用程序。

一个非常重要的方面(也许是bricelam说您需要删除历史记录表的原因)是,如果该表中的AutomaticMigration记录比您的一个手动迁移更新,那么您将遇到错误的时间。因为迁移者使用日期来整理它需要做的工作。

因此,如果有系统仍然自动升级到最新的自动升级模型,那么你有点腌渍。


5
2018-06-28 10:41



吸取的教训还包括:如果涉及多个数据库,请不要使用自动迁移。所以当你发展它的罚款。但是,如果您部署到多台计算机,或在团队中一起工作。然后在共享应用程序之前将其关闭(!) - Wouter Schut