【问题标题】:How to apply EF Core migrations if you should not use MigrateAsync() for production environments?如果不应将 MigrateAsync() 用于生产环境,如何应用 EF Core 迁移?
【发布时间】:2021-08-18 01:03:59
【问题描述】:

我创建了一个新的 .Net 5 项目并想使用 EF Core。我使用

自动生成了多个migration.cs文件

dotnet ef migrations add MyMigration

并希望应用它们(用于开发和生产)。我知道MigrateAsync 方法,所以我了解了如何在启动时调用此方法

https://andrewlock.net/running-async-tasks-on-app-startup-in-asp-net-core-part-1/

但我在任何地方都读到此方法不应用于生产,因为这些迁移不会在单个事务中执行(错误不会回滚)。

不幸的是,无论环境如何,关于如何做到这一点的资源并不多,我找到了这篇文章

https://www.thereformedprogrammer.net/handling-entity-framework-core-database-migrations-in-production-part-2

一个选项可以是调用迁移的控制台应用程序

https://www.thereformedprogrammer.net/handling-entity-framework-core-database-migrations-in-production-part-2/#1b-calling-context-database-migrate-via-a-console-app-or-admin-command

但我无法理解这种方法的区别,因为它没有解决事务问题?

在开发/生产期间应用迁移的最佳做法是什么?

  • 在自动生成迁移之后,我非常喜欢简单,dotnet ef database update 是否可以胜任这项工作并且我不需要使用其他工具?

  • 创建一个控制台应用程序,从迁移中生成 .sql 文件,安装 DbUp 并将其用于迁移部分?

【问题讨论】:

    标签: c# entity-framework-core dbup


    【解决方案1】:

    最有效的方法在很大程度上取决于部署管道的工作方式 - 在生产之前有多少环境、发布周期、部署的哪些部分是自动化的。没有通用的“最佳实践”——每种处理迁移的方式都有自己的权衡需要注意。根据您的需求和期望选择升级程序。

    在为中型项目(大约 70 个表)设置 EF Core 迁移时,我尝试了几种可能的方法。我对过程的观察以及最终的结果:

    1. 您希望在更改模型和部署到生产之间的某个位置获得迁移 SQL,如果只是为了查看它,以防有任何可能导致回滚问题的重大更改。我们决定使用 dbcontext 直接在项目中进行迁移,并为每个可能部署到任何环境的构建生成一个迁移脚本(使用dotnet ef migrations script --idempotent)——在我们的例子中,每次推送到主干或发布都有一个 CI 步骤分支。
    2. 将迁移 SQL 置于版本控制中,并将 SQL 视为数据库结构的真实来源,当您想要保留某些列以进行备份或向后兼容时,可以手动修改脚本。另一种选择是将您的数据模型视为数据库模式的参考,并将迁移 SQL 视为不保留的中间步骤,这使得整个过程更容易自动化,但需要您直接在数据模型中处理特殊情况。李>
    3. 在生成迁移脚本时使用--idempotent 标志为您提供了一个脚本,您可以将其重新应用于数据库架构,而不管它处于什么架构版本,让它只执行尚未执行的步骤。这意味着您可以将相同的迁移脚本重新应用到已迁移的数据库而不会破坏架构。如果您有不同版本的应用程序在不同的环境(开发环境、暂存环境和生产环境)中并行运行,则可以避免手动跟踪您需要应用的迁移脚本版本以及应用顺序的问题。
    4. 当您迁移 SQL 时,您可以将本机用于您的数据库工具,以便将它们应用到目标环境 - 例如,sqlcmd 用于 SQL Server,psql 用于 postgres。这还有一个好处是让具有更高权限(架构修改)的单独用户处理迁移,而您的应用程序在有限的权限下工作,通常无法触及架构。
    5. 应用数据库迁移是应用程序部署的一部分,而不是应用程序启动 - 如果您有某种部署自动化,这可能是对目标数据库执行迁移的最佳位置 - 数据库本机客户端是 @987654327 的一个很好的替代品@,选择你喜欢的。将迁移与应用程序启动分开还使您能够针对不匹配但仍兼容的数据库模式运行应用程序——这在例如您正在进行部署部署。
    6. 架构升级的大多数问题来自破坏版本之间的架构兼容性 - 避免这种情况需要在处理数据模型时注意向后/向前兼容性并将重大更改拆分为单独的版本,以保持至少单步向后/向前兼容性 -您是否需要它取决于您的项目,这是您应该决定的。我们针对当前数据库模式运行先前版本的完整集成测试套件,并针对先前数据库模式运行当前版本,以确保在两个后续版本之间没有引入重大更改 - 任何移动多个版本的部署都将一一推出迁移,假设该迁移脚本或应用程序启动可以包括从旧模型到新模型的数据转换。

    总结一下:生成迁移 SQL 并在版本部署上使用本机工具或 DbUp 可以让您在一定程度上手动控制迁移过程,并且可以通过自动化部署过程来实现易用性。出于开发目的,您还可以在应用程序启动时添加自动迁移,最好仅在环境设置为 Development 时应用 - 只要团队中的每个人都有自己的开发数据库(本地 SQL,共享服务器上的个人,如果您使用 SQL,则使用 filedb)无需担心冲突。

    【讨论】:

    • DbUp 的一些链接:dbup.github.io - 库; dbup.readthedocs.io/en/latest - 文档
    • 一个问题 - 我可以使用工具集 DbUp 来应用由实体框架(EF 核心,代码优先)生成的迁移代码 (C#),就像 dotnet ef database update --context myDbContext --project myDatabaseProject在 PM 控制台中会这样做吗?
    • DbUp 要求您拥有要应用的 SQL 脚本,因此您仍需要使用 EF 生成这些脚本。这意味着您仍然有两个步骤:1) 生成迁移脚本,2) 将脚本应用到数据库。在我提供的文章中,DbUp 可以将 sqlcmd/psql 替换为与 SQL 服务器无关的工具(脚本仍然可能需要特定于服务器),但不会做任何事情。
    • 好的,我可以使用 dotnet ef migrations script -i -o C:\temp\migration.sql --project "myDBProject.csproj" --startup-project "myDBProject.csproj" 预先创建 SQL 脚本,然后将该文件添加到 DbUp。
    猜你喜欢
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 2018-10-02
    • 2016-11-06
    相关资源
    最近更新 更多