在显式迁移中捕获自动迁移的最小破坏性方法?

时间:2017-12-19 17:16:09

标签: entity-framework ef-migrations

我有点腌菜。我使用EF继承了一个项目,其中:

  • 最初启用了自动迁移
  • 添加了一些自动迁移
  • 添加了一些明确的迁移
  • 随后关闭了自动迁移

由于部署此代码的计算机与开发计算机并行运行,因此它们都具有完整的工作DB,因此没有任何损失。

我担心的是,如果我们曾部署到另一台计算机,则只会应用显式迁移。事实上,我发现在尝试在新的开发机器上运行项目时都是如此。

现在,我已经能够通过生成SQL创建脚本并在新机器上运行这些脚本来哄骗它。显然,这不是一个长期的解决方案。

我可以看到的一个选项是清除所有迁移和迁移历史记录(在__MigrationHistory)表格中,并创建一个新的"首字母"迁移,这将涵盖一切。我对此的担心是,我必须在运行代码的每台机器上执行此手术 - 包括生产服务器。

有没有办法回溯性地将初始自动迁移捕获到新的显式迁移中,只能在完全新鲜的环境中运行?

1 个答案:

答案 0 :(得分:0)

如果您有能力手动更新数据库,则可以选择运行Update-Database -Script。然后,您将能够看到每个迁移(甚至是自动迁移)和SQL命令,因为它们将按顺序应用。 继续保存整个SQL文件,因为在接下来的步骤中你需要它。

接下来,查看每个命令块,这些命令块将由包含巨大Base64字符串的INSERT命令分隔。您将看到每个迁移的步骤都被拆分并按顺序排列,包括自动迁移。对于这些对中的每一对,我们实际上只需要INSERT命令之上和上一次迁移的INSERT命令之下的所有内容。我将这些称为迁移操作。

当然,我意识到这需要一些大规模的时间,但是接下来运行Add-Migration -IgnoreChanges来构建一个空迁移,然后在Up()方法中添加一个新的Sql()操作并复制当前的迁移操作(即Sql("<your_awesome_script>"))。您可能需要制作相应的Down()才能安全。

接下来,返回并查看您正在使用的自动转移之前和之后的迁移的TimeStamps。这将在INSERT命令中作为第一个参数,如201710152132114_<MigrationName>。在这两者之间选择一个DateTime,然后使用该DateTime命名新迁移的.cs文件。这将在您的解决方案中正确地进行迁移,以备将来使用。

最后,打开迁移的.Designer.cs文件,并在ImigrationMetadata.Id上的get内部替换现有的Id字符串,即您创建的新迁移名称。这将是EF将以编程方式使用来订购迁移操作的内容。

如果要移动到已经应用了某些迁移的新计算机,请尝试查看它正在使用的数据库实例,并查看__MigrationHistory表中最新条目的ID。然后在您的开发环境中还原针对 迁移的迁移,并按照上面列出的步骤进行每次自动迁移。如果您可以转换所有这样的自动迁移,那么您将能够部署到新环境,以便将来进行所有显式迁移。

我肯定建议不要在生产机器上尝试这个,直到它在开发和测试环境中为你工作。