用 EF 迁移更新生产数据库是否可以?

根据 这篇博文,大多数使用 EF 迁移的公司应该不会用 EF 迁移来更新生产数据库的数据库模式。相反,博客文章的作者建议使用 Schema 更新脚本作为部署过程的一部分。

我已经使用 Schema 更新脚本好几年了,当它们工作的时候,我计划在将来使用 EF 迁移,原因如下:

  • 更快的部署,更少的停机时间
  • 更简单的部署程序
  • 与使用 T-SQL 相比,迁移现有数据要容易得多
  • 一种更易于理解的等待应用的更改语法(在传统环境中,带有干净 C # 语法的 DbImmigration 类与笨重的 T-SQL 迁移脚本相比)。
  • 如果新软件版本的部署失败,那么旧的 db 模式有一个简单而快速的下降路径

我能想到的禁止使用 EF 迁移生产数据库的一个原因是,如果数据库模式只是由 DBA 而不是开发人员修改的话。但是,我既是 DBA 又是开发人员,所以这对我来说并不重要。

那么,使用 EF 更新生产数据库的风险是什么?

编辑: 我想补充的是,正如 solomon8718已经建议的那样,我总是将生产数据库的一个新副本拉到我的登台服务器上,并在将它们应用到生产服务器之前测试在登台服务器上应用的 EF 迁移。无论我是否使用 EF 迁移,这对于任何生产系统的模式更新都是至关重要的。

28214 次浏览

好吧,不管怎样我会试着回答的。我会说不,没有理由不在生产中使用代码优先迁移。毕竟,如果不能一直使用这个易于使用的系统,那么它还有什么意义呢?

我所看到的最大的问题是任何系统都可能出现的问题,这一点您已经注意到了。只要整个团队(如果适用,还包括 DBA)都支持,我认为允许 EF 通过迁移来管理模式就不会那么复杂,因此比传统的基于脚本的管理更不容易出错。在生产系统上执行迁移之前,我仍然需要备份,但是无论如何都要这样做。

也没有任何证据表明 DBA 不能从 VisualStudio 执行迁移。访问仍然可以在数据库级别用特权锁定,并且他/她可以在执行实际操作之前检查迁移(如果需要,可以使用有用的 SQL 导出格式,使用 -Script)。然后它们仍然在控制之中,但是您可以使用代码优先迁移。见鬼,他们甚至可能会喜欢它!

更新: 由于提出了 SPROCs 和 TVF,我们也处理这些迁移,尽管它们实际上是通过在 Up()中使用 DbMigration.Sql()调用的直接 SQL 语句完成的,在 Down()中使用相反的语句(对于简单的 SPROCs,你也可以使用 CreateStoredProcedureDropStoredProcedure,但我认为你仍然需要在 SQL 中定义主体本身)。我想你可以说这是一个警告; 目前还没有一种方法可以完全用 C # 编写一个完整的、全面的数据库。但是,可以使用包含 SQL 脚本的迁移来管理整个架构。我们从这个过程中发现的一个好处是,您可以使用 C # 配置文件作为模式对象名称(例如,不同的生产服务器名称与 dev 名称)和一个简单的 String.Format,结合配置文件本身的 XML 转换。

我在几个项目的制作中使用它。一旦你掌握了窍门,我想就没问题了。

在开发期间,您可以保持自动迁移,但是在最后,您可以直接从包管理器控制台连接到 live db 并生成迁移。它将为所有更改提供一次迁移。

但总是始终使用 -script选项与 update-database和触发自己的 SQL。

我还建议不要使用来自 Web 部署的 update db 选项。这样就没有办法知道有多少迁移已经因为错误而启动。我遇到过几次这样的麻烦。所以最好获取 SQL 并手动激活它。

是的,有充分的理由 没有使用自动化系统,如代码优先迁移,使 制作数据库的变化。但一如既往,规则总有例外。

  1. 前面提到的一个原因是访问权限,它与组织的变更管理规则和安全策略直接相关。

  2. 另一个原因是您对迁移工具本身的信任程度。我们确定这个工具没有 bug 吗?如果工具中途失败会发生什么?您确定您有最新的备份以及在需要时可以回滚的过程吗?

  3. 更改脚本可能会执行意外的或低效的脚本。我曾经遇到过这样的情况: sql 生成的数据将数据复制到一个临时表中,删除原始表,然后重新创建原始表,以便在您意外(或有意)更改列的出现顺序或重命名表时添加一个新列。如果涉及数百万条记录,可能会导致严重的性能问题。

我的建议是:

假设您有一个反映您的生产模式的 Staging 数据库,那么使用迁移工具针对该系统生成其更改脚本。在运行之前,我们通常从一个新的生产副本恢复阶段数据库。然后,我们手动检查更改脚本以检查问题。之后,我们对阶段数据库运行脚本,以确保它正确执行,并且所有预期的更改都发生了。现在我们可以确定,这些脚本在生产环境中运行和执行预期的更改都是安全的。这个过程将解决我上面列出的所有三个问题。

我发现的另一个警告是: 如果你有几个网站使用相同的数据上下文,你需要确保所有的网站同时更新。否则,网站之间可能会不断发生数据库更新/降级之争。除此之外,我觉得还不错。

编辑: 开始在生产中使用 EF 迁移一年后,我自己的观点:

EF 迁移实际上非常酷,即使是对于生产用途,只要您

  1. 在临时系统上测试迁移。在运行集成测试之前,我通过在 CI 服务器上一直向下和向上迁移来测试所有的迁移。
  2. 不要自动触发迁移,而是使用由管理员启动的批处理文件。这基本上与在 SSMS 中手动运行迁移的 sql 相同。