持续部署的 EF Core Code First 运行时迁移回滚策略

Posted

技术标签:

【中文标题】持续部署的 EF Core Code First 运行时迁移回滚策略【英文标题】:EF Core Code First Runtime Migration Rollback Strategy with Continuous Deployment 【发布时间】:2020-06-19 17:45:04 【问题描述】:

我有一个在启动时使用 EF Core 运行时迁移的服务:

var migrator = dbContext.Database.GetService<IMigrator>();
await migrator.MigrateAsync("targetMigration", cancellationToken);

要生成迁移,我首先更新 DbContext 类,然后执行“dotnet ef migrations add”来生成迁移代码。

发生迁移后,部署的升级可能会自动回滚到以前的版本。例如,如果健康检查或测试失败。在这种情况下,我希望以前版本的应用程序能够自动回滚迁移。我知道 MigrateAsync 可以恢复迁移,但在我当前的工作流程中,迁移代码不会出现在以前版本的代码中,所以我不确定它是否能够恢复迁移。

我可以想到这样的工作流程:

    更改 DbContext 并运行“dotnet ef add migration”生成迁移代码

    还原 DbContext 更改并部署应用程序,以便存在迁移“n”的代码,但 MigrateAsync 中的目标迁移和 DbContext 的版本为“n-1”

    重新应用 DbContext 更改,将 MigrateAsync 更改为目标迁移 'n',然后部署应用程序

但这似乎很尴尬,我不确定是否有必要,以及它是否一定会起作用。

什么是使用 EF Core 部署代码优先运行时迁移的好策略,这样如果部署了以前的版本,迁移可以自动回滚?

【问题讨论】:

【参考方案1】:

据我所知,EF 没有为你准备任何东西,在 prod 中来回迁移真的很难,而且,你必须考虑到许多迁移会造成数据丢失。

首先,您需要创建一个流程,当更改必须经过很好的测试时,当更改投入生产时,您应该 99% 确定生产中不会出现回滚。

正如您所说,您需要最新版本的代码,否则,EF 将不知道“down”应该做什么。

在我们当前的系统中,我们分析每个迁移,如果是新表或简单的东西,我们只需从 CI 运行迁移。如果它是更复杂的东西,或者我们需要更复杂的移动(数百万行的表修改),我们只需手动完成,因此我们可以将数据发送到临时表,填充空数据或使用我们刚刚 @987654321 的特殊功能@ 并使用它。

dotnet ef migrations script 20190725054716_Add_new_tables

这是一个非常困难的问题,Java 和 JPA 共享相同的问题来生成历史记录。

这些迁移生成器非常适合开发,但很难用于生产,不断变化的环境,特别是当您需要像您一样来回切换时,另一种选择是使用其他工具来处理为这种情况做好更好准备的迁移,喜欢liquibase

另一个想法可以找到here:

我最终创建了一个执行迁移的自定义工具 智能地自动确定哪个模型(上下文) 用于迁移的程序集。

【讨论】:

感谢您的回答。就我而言,升级是针对不同的服务和分区以滚动方式完成的,它们都有自己的数据库,因此使用部署的代码进行迁移似乎是必要的。

以上是关于持续部署的 EF Core Code First 运行时迁移回滚策略的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 EF Core Code-First 创建具有子类别的类别表? [复制]

EF Core开发模式之Code First

EF Core 2.0使用MsSql/Mysql实现DB First和Code First

如何使用EF Core Code-First桥接自己的表

如何在 EF Core Code First 中自定义迁移生成?

用于 ASP.NET Core 应用程序的 EF Code First 迁移替代方案