根据this blog post,大多数使用EF迁移的公司都不会使用EF迁移更新生产数据库的数据库模式。相反,博客文章的作者建议使用Schema更新脚本作为部署过程的一部分。
我已经使用了Schema更新脚本几年了,当它们工作时,我计划将来使用EF迁移,原因如下:
我可以想到的一个原因是,如果数据库模式仅由DBA而不是开发人员更改,那么禁止使用EF来迁移生产数据库。但是,我既是DBA又是开发人员,所以这在我的案例中并不重要。
那么,使用EF更新生产数据库会有什么风险?
编辑:我想补充一点,正如solomon8718已经建议的那样,我总是将生产数据库的新副本提取到我的登台服务器,并在将它们应用到生产之前测试要在登台服务器上应用的EF迁移服务器。对于生产系统的任何架构更新,IMO都是必不可少的,无论我是否使用EF迁移。
答案 0 :(得分:32)
好吧,无论如何我都会尝试回答。我会说不,没有理由不在生产中使用Code First Migrations。毕竟,如果你不能一直使用这个易于使用的系统的重点是什么?
我看到的最大问题是您可以使用任何系统遇到的所有问题,您已经注意到了这些问题。只要整个团队(如果适用,包括DBA)与我一起使用,我认为允许EF通过迁移来管理模式不那么复杂,因此比传统的基于脚本的管理更不容易出错。在生产系统上执行迁移之前,我仍然需要备份,但无论如何你都会这样做。
没有任何迹象表明DBA也无法从Visual Studio执行迁移。仍然可以使用数据库级别的权限锁定访问权限,并且他/她可以在执行实际操作之前查看迁移(如果需要,使用-Script
以有用的SQL导出格式)。然后他们仍然可以控制,但您可以使用代码优先迁移。天啊,他们甚至可能最终喜欢它!
更新:由于SPROC和TVF已经启动,我们也处理迁移中的那些,尽管它们实际上是使用DbMigration.Sql()
中Up()
调用的直接SQL语句完成的,并且Down()
中的它们相反(对于简单的SPROC,您也可以使用CreateStoredProcedure
和DropStoredProcedure
,但我认为您仍然需要在SQL中定义正文本身)。我想你可以说这是一个警告;还没有一种方法可以将整个数据库完全用C#编写。但是,您可以使用包含SQL脚本的迁移来管理整个架构。我们从此过程中发现的一个好处是,您可以使用C#配置文件作为模式对象名称(例如,生产与dev的不同服务器名称),使用简单的String.Format
,并结合XML Transformation for the config文件本身。
答案 1 :(得分:32)
是的,有充分的理由不使用代码优先迁移等自动化系统来进行生产数据库更改。但一如既往,规则有例外。
提到的一个原因是访问权限,这与您组织的变更管理规则和安全政策直接相关。
另一个原因是您对迁移工具本身的信任程度。我们确定该工具没有错误吗?如果工具在中途失败会发生什么?你确定你有最新的备份和需要回滚的过程吗?
更改脚本可能会执行意外或低效的脚本。我经历过这样的情况,即生成的sql将数据复制到临时表中,删除原始表,然后重新创建原始表,以便在意外(或故意)更改列的顺序时添加新列等内容出现,或重命名表时。如果涉及数百万条记录,则可能会导致严重的性能问题。
假设您有一个镜像生产模式的临时数据库,请使用迁移工具生成针对该系统的更改脚本。我们通常在运行之前从新的生产副本中恢复舞台数据库。然后,我们手动检查更改脚本以检查问题。之后,我们针对舞台数据库运行脚本,以确保它正确执行并且预期发生了所有更改。现在我们确信脚本在生产中运行安全并执行预期的更改。这个过程将解决我上面列出的所有三个问题。
答案 2 :(得分:6)
我发现另一个警告:如果您有多个网站使用相同的数据上下文,则需要确保所有网站同时更新。否则,网站之间可能会有持续的数据库更新/降级争用。除此之外,它对我来说很好。
编辑:我开始在生产中使用EF迁移一年后的观点:
EF迁移实际上非常酷,即使是生产用途,只要你
答案 3 :(得分:2)
我在生产中用于几个项目。一旦掌握了它,我认为它很好。
在开发期间,您可以保持自动迁移,但最后您可以直接从程序包管理器控制台连接到实时数据库并生成迁移。它将为您提供一次迁移以进行所有更改。
但始终始终将-script
选项与update-database
一起使用并自行激活SQL。
我还建议不要使用web部署中的update db选项。这样就没有办法说出错误已经触发了多少迁移。我曾经遇到过几次麻烦。因此最好获取SQL并手动触发它。