使用EF迁移更新生产数据库可以吗?

根据这篇博客文章,大多数使用EF迁移的公司都没有用EF迁移来更新生产数据库的数据库模式。 相反,博客文章的作者build议使用架构更新脚本作为部署过程的一部分。

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

  • 更快的部署,更less的停机时间
  • 更简单的部署过程
  • 现有数据的迁移比使用T-SQL更容易
  • 一个更易于理解的等待应用的变化语法(在传统环境中,使用干净的C#语法的DbMigration类与笨重的T-SQL迁移脚本)。
  • 如果新软件版本的部署失败,那么旧的数据库模式有一个简单而快速的降级path

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

那么,使用EF更新生产数据库有哪些风险呢?

编辑:我想补充说,正如solomon8718已经build议,我总是拉生产数据库的全新副本到我的登台服务器,并testingEF Migrations应用在登台服务器上,然后将其应用到生产服务器。 IMO对于生产系统的任何模式更新都是必不可less的,无论我是否使用EF迁移。

那么,我会尽力回答。 我会说,不,没有理由不使用Code First Migrations进行生产。 毕竟,这个易于使用的系统,如果你不能完全采取的话,这有什么意义呢?

我所看到的最大的问题是任何你已经注意到的系统都可能遇到的问题。 只要整个团队(包括DBA,如果适用的话)都包含在内,我认为允许EF通过迁移来pipe理架构不那么复杂,因此比传统的基于脚本的pipe理更less出错。 在生产系统上执行迁移之前,我仍然会进行备份,但是无论如何你都要这样做。

没有什么说DBA无法从Visual Studio执行迁移。 访问权限仍然可以在数据库级别被locking,并且他/她可以在执行实际操作之前检查迁移(如果需要,可以使用-Script的有用的SQL导出格式)。 然后他们仍然在控制之中,但是您可以使用代码优先的迁移。 地狱,他们甚至可能会喜欢它!

更新:自从SPROC和TVF被引入,我们也在迁移中处理这些迁移,尽pipe实际上它们是在Up()使用DbMigration.Sql()调用直接使用SQL语句完成的,而在Down() (对于简单的DropStoredProcedure ,你也可以使用CreateStoredProcedureDropStoredProcedure ,但是我认为你仍然需要在SQL中定义主体本身)。 我想你可以说这是一个警告, 目前还没有一种方法可以将完整的数据库纯粹用C#编写。 但是,您可以使用包含SQL脚本的迁移来pipe理整个模式。 我们从这个过程中发现的一个好处是,您可以使用C#configuration文件作为模式对象名称(例如生产vs dev的不同服务器名称),并使用简单的String.Format ,并将XML Transformation用于configuration文件本身。

是的,有很好的理由使用自动化系统,如Code First Migrations来改变生产数据库。 但是,一如既往,规则有例外。

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

  2. 另一个原因是您对Migrations工具本身的信任程度。 我们确定这个工具没有错误吗? 如果该工具中途失败会发生什么? 你确定你有最新的备份和一个stream程,如果需要回滚?

  3. 更改脚本可能会执行意外或低效的脚本。 我遇到过这样的情况:生成的sql将数据复制到临时表中,删除原始表,然后重新创build原始表,例如,如果意外(或故意)更改列出现的顺序,或者当你重命名表。 如果涉及数百万条logging,可能会导致严重的性能问题。

我的推荐:

假设您有一个映射生产模式的临时数据库,请使用迁移工具针对该系统生成其更改脚本。 我们通常在运行之前从新的生产副本中恢复舞台数据库。 然后,我们手动检查更改脚本以检查问题。 之后,我们对我们的舞台数据库运行脚本,以确保它正确执行,并预期所有的变化发生。 现在我们确信这些脚本既可以安全地在生产环境中运行,也可以执行预期的更改。 这个过程将解决我上面列出的所有三个问题。

另外一个警告我发现:如果你有几个网站使用相同的数据上下文,你需要确保它们都被同时更新。 否则,网站之间可能会有一个不断更新/降级的数据库争夺战。 除此之外,它为我工作得很好。

编辑:我开始在生产中使用EF迁移一年后的视angular:

EF Migrations实际上非常酷,即使是生产使用,只要你

  1. 在登台系统上testing迁移。 在运行集成testing之前,我通过在CI服务器上一直向下和向上迁移来testing所有迁移。
  2. 不要自动触发迁移,而是使用由pipe理员启动的batch file。 这与在SSMS中手动运行sql进行迁移基本相同。

我用它来生产几个项目。 一旦你掌握了它,我认为它很好。

在开发过程中,您可以保持自动迁移,但最终您可以直接从包pipe理器控制台连接到实时数据库,并生成迁移。 它会给你一个迁移所有的变化。

但是始终总是使用update-database-script选项并自己启动SQL。

我也build议不使用web部署的更新数据库选项。 那样的话,就没有办法知道有多less迁移已经因错误而被解雇了。 这几次我遇到了麻烦。 所以最好得到SQL并手动启动它。