如何在生产环境下用好EFCore

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

作者:Jon P Smith

在生产中运用EFCore的模式实战

这是使用EF Core迁移数据库的系列文章中的第二篇。本文着眼于将迁移应用于数据库,并从第1部分开始,该部分介绍了如何创建迁移脚本。如果您还没有阅读第1部分,那么本文的某些部分将毫无意义,因此这里是第1部分的快速回顾。

•可以将两种类型的迁移应用于数据库:•添加新的表,列等,称为不间断的更改(简单)。•更改列/表并需要复制数据,这称为重大更改(困难)。•将迁移应用于数据库的主要方法有两种•使用EF Core迁移功能•使用EF Core创建迁移,然后手动修改迁移。•使用第三方迁移构建器在C#中编写迁移。•使用SQL数据库比较工具比较数据库并输出SQL更改脚本。•通过复制EF Core的SQL编写自己的SQL迁移脚本。

因此,既然您现在知道如何创建迁移脚本,那么我将研究可以将迁移应用于生产数据库的不同方式,以及这些方式所具有的利弊。

TL; DR –内容摘要

注意:单击链接可直接转到涵盖该点的部分。

•您具有影响迁移方法可以使用的应用程序的类型。•您必须考虑可能发生的错误并制定计划。•有四种方法可以将迁移应用于数据库•在启动时调用context.Database.Migrate()Very Easy,但是存在一些严重的问题,限制了它的实用性。•通过控制台应用程序调用context.Database.Migrate()-Easy,并且效果很好,尤其是在部署管道中•将EF Core迁移输出为SQL脚本并在目标数据库上执行该脚本 -Hard,但是却能提供很好的控制。•使用数据库迁移应用程序工具来应用您自己的SQL脚本 -Hard,但是您却可以很好地控制。•应用迁移的三个不同级别。•在迁移数据库时停止应用程序是最安全的选择,但并非总是可能的。•在应用程序运行时,可以将某些(但不是全部)不间断的更改应用于数据库。•对于连续服务应用程序(7*24小时运行的服务),要应用重大更改需要五个步骤。

场景分析–您的产品是哪种应用程序?

在第1部分中,我们着重于创建“有效”的迁移,以及迁移是不间断的变更还是重大变更(请参阅本文开头的快速定义,或第1部分中的此链接。

现在,我们正在考虑将迁移应用于数据库,但是我们拥有的选项取决于正在访问数据库的一个或多个应用程序。这是您需要考虑的问题。

1.是只有一个应用程序访问该数据库,还是您的应用程序是横向扩展的Web应用程序,即,同时运行多个版本的应用程序。如果您的应用程序是横向扩展,则将删除其中一个选项。2.您可以在将迁移应用到数据库时停止应用程序,还是您的应用程序提供7*24小时连续服务?在应用重大变更方面,更新连续服务应用程序会带来一些挑战。

在迁移生产数据库时,有点偏执是可以的。

正如我在第1部分末尾所说的那样-当您将迁移应用于生产数据库时,最恐怖的部分到来了。更改包含关键业务数据需求(需求!)的数据库,请仔细计划和测试。您需要考虑如果(何时!)迁移因错误而失败时该怎么办。

在考虑应用迁移的不同方法时,您应该脑海中浮现“如果有错误会发生什么?”。这可能会促使您采用更复杂的迁移方法,因为它更易于测试或还原。我不能为您提供规则或建议,因为每个系统都不同,但是对故障有点偏执并不是一件坏事。我应该让您构建一个更健壮的用于迁移应用程序及其数据库的系统。

第2部分:如何将迁移应用于数据库。

下面的列表提供了将迁移应用于数据库的不同方法。我列出了EF Core案例的三个选项:第一个是最简单的,但是它有其他两个选项所没有的限制。SQL迁移没有实际限制,但确实需要数据库迁移应用程序工具才能以正确的顺序应用SQL脚本。

这是您可以应用迁移的方法列表。

1.EFCore迁移1.在启动时调用context.Database.Migrate()2.通过控制台应用程序或管理命令调用context.Database.Migrate()3.将迁移输出作为SQL脚本输出,然后在目标数据库上执行该脚本。2.SQL迁移1.使用数据库迁移应用程序工具。

最后,如何应用迁移取决于迁移类型(中断或不中断)和要更新的应用程序类型(单个应用程序,并行运行的多个应用程序或必须停止的应用程序)。这是所有这些排列的图表。

外部的深蓝色表示可以在所有情况下都应用SQL迁移,而内部较浅的方框表示可以在其中添加不同类型的EF Core迁移。以下是有关该图的一些澄清说明:

•该图显示了标准EF迁移和手工修改的EF迁移,但是当我谈论应用迁移时,两者之间没有区别-我们很简单地应用EF Core迁移。•图中的“五个阶段的应用程序更新”红色框表示您需要对无法停止的应用程序进行重大更改所需要的复杂阶段。我将在文章末尾介绍。

现在,我将详细介绍应用迁移的每种方式。

1a。在启动时调用context.Database.Migrate()

到目前为止,这是应用迁移的最简单方法,但是它有一个很大的局限性–您不应同时运行Migrate方法的多个实例。如果横向扩展Web应用程序,则可能会发生这种情况。引用安德鲁·洛克(Andrew Lock)的话:“

我们不能保证这会给您带来麻烦,但是除非您非常谨慎地确保幂等更新和错误处理,否则您很可能会陷入困境

” –请参阅他的帖子的这一部分“ 在ASP.NET Core中的应用启动时运行异步任务[1] ”。

好处·相对容易实现(请参阅提示) ·确保在应用程序运行之前数据库是最新的。
坏处·不得并行运行两个或多个Migrate方法。·如果迁移有错误,则您的应用程序将不可用。·难以诊断启动错误
局限性不适用于连续服务系统
提示我非常喜欢Andrew Lock的文章中的在启动时运行迁移的选项[2]。我在一些使用内存数据库的演示系统中使用了类似的方法,这些数据库需要初始化(请参见本示例[3]
我的建议如果您正在运行单个Web应用程序或类似的Web应用程序,并且可以在没有人使用它的情况下更新系统,那么这可能对您有用。我没有像我使用的许多系统那样使用横向扩展。

1b。通过控制台应用程序或管理命令调用context.Database.Migrate()

如果您不能并行运行多个Migrate方法,那么确保此方法的一种方法是在设计为仅执行Migrate方法的独立应用程序内调用Migrate方法。您可以在主Web应用程序解决方案中添加一个控制台应用程序项目,该项目可以访问DbContext并可以调用Migrate。您既可以自己运行它,也可以让您的部署系统运行它(EF6.x用户注意–这等效于运行Migrate.exe,但其中已编译应用程序dll)。

好处·它适用于所有情况。·与部署系统配合良好。
坏处还有更多工作。
局限性–无–,但请注意持续进行的五阶段应用程序更新
提示如果您的控制台应用程序使用连接字符串来定义要将迁移应用到哪个数据库,那么它将更易于在部署管道中使用。
我的建议如果您具有部署管道,那么这是一个不错的选择,因为您可以在部署过程中执行控制台应用程序。如果您是手动应用迁移,则有命令Update-Database。

1c。将EF Core迁移转换为脚本并将其应用于数据库

通过使用脚本迁移命令EF Core会将特定的迁移或默认情况下的所有迁移转换为SQL脚本。然后,您可以使用可以在要更新的特定数据库上执行SQL的方法来应用此方法。您可以在SQL Server Management Studio中手动执行SQL ,但是通常您的发布管道中有一些内容可以在适当的时间执行。

好处·它适用于所有情况。·与可以使用SQL脚本的部署系统一起很好地工作。·您可以在运行SQL之前先查看它,看看它是否正常。
坏处·比控制台应用程序(1b)更多的工作 ·您需要一些应用程序将脚本应用于正确的数据库。
局限性–无–,但请注意持续进行的五阶段应用程序更新
提示SQL包含用于更新迁移历史记录的代码,但是您必须在Script-Migration命令中包括idempotent选项,以获取阻止两次应用迁移的检查。
我的建议如果您想使用EF Core的Migrate方法,那么我建议您使用控制台应用程序1b。它与使用脚本一样安全,并且执行相同的工作。但是,如果您的管道已经可以使用SQL更改脚本,那么这非常适合您。

2a。使用迁移工具应用SQL脚本

如果创建了一系列SQL迁移脚本,则需要以下步骤:a)以正确的顺序应用它们,b)仅应用一次。EF Core的迁移包含执行“正确顺序”和“仅一次”规则的代码,但是当我们编写自己的迁移脚本时,我们需要一个可以提供这些功能的工具。

我和其他许多人使用了一个名为DbUp的开源库,该库提供了这些功能(以及更多功能),还支持多种数据库类型。我按字母顺序排列迁移脚本,例如“ Script0001 –初始迁移”,“ Script0002 –添加种子数据”以供DbUp应用。就像EF Core迁移一样,DbUp使用一个表来列出哪些迁移已应用到数据库,并且仅在该表中没有迁移时才应用。

还可以使用其他迁移工具,例如Octopus Deploy和各种RedGate工具(但我没有使用过它们,因此请检查它们是否具有正确的功能)。

好处·它适用于所有情况。与部署系统配合良好。
坏处·您必须管理脚本。
局限性–无–,但请注意持续进行五阶段应用程序更新
*

提示 *

(适用于DbUp)
·我制作了一个控制台应用程序,该应用程序接受连接字符串,然后运行DbUp,因此可以在部署管道中使用它。·为了进行测试,我使运行DbUp的方法在“仅以调试模式运行”单元测试中可用于我的单元测试程序集,该方法使用我的CompareEfSql工具正确迁移了本地数据库(请参阅本系列第1部分中有关测试迁移的部分。
我的建议使用EF Core的项目上使用这种方法。

应用程序和应用程序迁移

将迁移应用于数据库时,可以停止应用程序,或者在某些情况下可以在迁移运行时应用迁移。在本节中,我将介绍为您提供的不同选项。

1.在迁移数据库时停止应用程序

这是最安全的选项,可与重大更改和不中断更改一起使用,但是您的用户和您的业务可能并不那么满意。我称其为“维护站点”。在“站点关闭”方法中,您不想在用户输入数据或完成订单时停止应用程序。这就是您或您的公司获得不良声誉的方式。

我早在2015年就遇到了这个问题,并且我创建了一种方法来警告人们该网站将要关闭,然后停止除管理员以外的所有人员访问该应用程序。我之所以选择这种方法,是因为对于正在使用的Web应用程序,此方法比支持破坏性更改同时保持Web应用程序运行的开销要小(我将在稍后介绍对连续服务应用程序进行中断)。通常在周末和晚上,您可能会遇到所使用服务的“此站点已关闭维护”。

注意:我写了一篇名为“ 如何使ASP.NET MVC网站“为了维护而停机 ””的文章,您可能希望看一下-该代码是针对ASP.NET MVC5的,因此需要一些工作才能使其正常工作。.NET Core,但该想法仍然有效。

在应用程序运行时应用不间断的迁移

从理论上讲,通过不间断的更改,您可以在旧应用程序运行时将其应用于数据库,但是有些问题可能会让您失望。例如,如果您添加了一个没有SQL默认值且不知道该新列的旧软件的新的非空列,并尝试插入新行,则您会收到一条SQL错误,因为旧软件没有提供了非空列的值。

但是,如果您知道不间断的迁移没有问题,那么在旧应用程序运行时应用迁移将为您的用户提供连续的服务。有多种方法可以执行此操作,具体取决于您选择了哪种迁移应用程序方法,想到的就是Azure的暂存槽(已经存在了很长时间)和更新的Azure Pipelines。

将重大更改应用于连续运行的应用程序:五阶段的应用程序更新。

最困难的工作是对不断运行的应用程序进行重大更改。在显示不同方法的图表中,右上方会显示一个名为“五阶段应用程序更新”的红色框。该名称来自以下事实:您需要分阶段迁移,通常为五个阶段,如下图所示。

注意:安德鲁·洛克(Andrew Lock)称赞我在上一节中描述的“添加不可为空的列”问题可以分三个阶段处理:a)添加新列但可为空,b)部署已知该列的新软件,以及c)将列更改为不可为空。

这是我的《EFCore》一书的第11.5.3节中的图表,该图显示了添加重大更改所需的五个阶段,这些更改将现有的CustomerAndAddress表分为两个表,Customers和Addresses。

如您所见,这样的更新创建起来很复杂,应用起来也很复杂,但这就是运行连续系统的成本。这五个阶段没有任何真正的替代方案,除了您永远不要对连续运行的系统应用重大更改(我听说有人说这是他们的方法)。

注意:我在我的书“ Entity Framework Core in Action[4] ”的11.5.3节中介绍了持续的,五个阶段的应用程序更新,您还可以在Neil Ford的“ Building Evolutionary Architectures ” 一书的第5章中找到有关此内容的内容。等。

结论

如果数据库中的数据和服务的可用性对组织很重要,那么您必须认真对待数据库迁移。在第1部分中,我介绍了创建迁移脚本的不同方法,并且本文介绍了如何将这些迁移应用于生产数据库。本系列文章的目的是为您提供各种选择,以及它们的优缺点,以便您可以就如何处理迁移做出明智的决定。

就像我在第一篇文章中所说的那样,我与EF迁移的第一个磨合是使用EF6。我非常了解EF6,并且写过《 Entity Framework Core in Action》一书,[5]我对EF Core的了解甚至更好。围绕迁移从EF6到EF Core的变化代表了EF Core中整个方法的变化。

EF6进行了很多“魔法”操作,使其更易于使用- 启动时自动迁移就是其中之一。问题是,当EF6的“魔法”效果不佳时,很难对其进行梳理。EF Core的迁移方法是由您决定如何在何处以及如何使用它-没有自动的“魔法”。EF Core迁移的许多其他小变化来自于聆听EF4到6的用户。

因此,在生产数据库上的迁移令人恐惧。我已经为您提供了一些有关选项的见解,但这仅是更改生产数据库的最低要求。需要根据需要添加备份,策略,产品前测试和部署管道,以构建可靠的系统。 

祝你能享受编码的快乐!

References

[1] 在ASP.NET Core中的应用启动时运行异步任务: https://andrewlock.net/running-async-tasks-on-app-startup-in-asp-net-core-part-1/
[2] 选项: https://andrewlock.net/running-async-tasks-on-app-startup-in-asp-net-core-part-1/#4-manually-running-tasks-in-program-cs
[3] 本示例: https://github.com/JonPSmith/EfCore.GenericServices/blob/master/RazorPageApp/Program.cs
[4] Entity Framework Core in Action: http://bit.ly/2m8KRAZ
[5] ,: http://bit.ly/2m8KRAZ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/308112.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

39. 组合总和020(思路+详解)

一:题目: 给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。 candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种…

8种方法解决vue创建项目报错:command failed: npm install --loglevel error

8种方法解决vue项目创建失败问题1、重建项目2、清除缓存3、重装淘宝源4、修改useTaobaoRegistry5、重装node6、删除npmrc文件7、 node版本问题8、css编辑工具选择9、管理员身份运行踩了这个巨大的坑!! 试了一个晚上终于找到了创建项目成功了T_T 当报错了…

40. 组合总和 II021(回溯法)

一:题目 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用一次。 注意:解集不能包含重复的组合。 示例 1:输入: candidates [10,1,2,…

.NET Core + Kubernetes:Helm

Helm[1] 作为 Kubernetes 体系的包管理工具,已经逐渐成为了应用分发标准,在 .NET 开发中,可以理解为与 NuGet 包类似。回顾之前文章中的介绍,Kubernetes 中单个服务的部署有时会涉及到多种资源类型,如:Depl…

vue项目中引入阿里图标iconfont

vue如何在创建好的项目中引入阿里图标iconfont呢,涉及到以下几个步骤: 1、首先先到阿里图标官方网站https://www.iconfont.cn/,先对账户进行登录,登录完成后任意选择几个图标加入购物车 2、加入购物车后,点击页面最右…

78. 子集022(回溯法)

一:题目 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出:…

vue项目中使用vue-router进行路由配置及嵌套多级路由

在vue项目中,很多时候我们需要二级路由或者三级路由来跳转页面,但大部分需求下我们都只用到了二级路由,有小伙伴就会发现,用到三级路由的时候,就会突然不知所措,是有新的方法呢,还是跟二级路由配…

解决流氓软件方法(亲测有效)

一:问题描述 本来我想在百度上下载一个API文档,我当然知道是取官网上下载了,但是我想要的是中文版,所以我就搜啊搜,搜到脚本之家 ,那里面可以下载,我记得以前在里面下载过东西,以为安全就去下载…

.NET Core:跨平台和开源,让我在框架中脱颖而出

自从 2016 年微软发布了 .NET Core 1.0,至今 4 年的时间里,.NET Core 历经 7 个正式版本和几十个 Preview 版本。.NET Core 作为最通用的框架,和其他软件框架不同的是,它面向 Windows、Linux 和 MacOS 多个平台,在桌面…

vue实现侧边折叠菜单栏手风琴效果

在我们做管理后台亦或是产品流程时,总是需要一个菜单栏或者导航栏来架起我们的产品架构,那么,如何用vue实现侧边折叠导航栏呢?接下来将一一介绍。 请先看效果演示图。 步骤1:先架构整个页面的布局,撰写html…

程序员过关斩将--解决分布式session问题

微信搜一搜架构师修行之路session 说到 session,我相信每个程序员都不陌生,或多或少在项目中使用过。session 这个词,其实是一个抽象的概念,它不像 Cookie 那样有着明确的定义。当大多数程序员谈论 session 的时候,可能…

如何将nodejs项目程序部署到阿里云服务器上

将nodejs项目程序部署到阿里云服务器上一、概述二、具体步骤1、拥有自己的服务器2、下载Xshell3、 oneinstack配置web环境4、 XShell连接远程主机5、更新系统软件6、在服务器上安装node环境7、部署项目到服务器上8、安装pm2并启动nodejs项目三、快捷指令1、linux的常用命令2、p…

101. 对称二叉树023(BFS)

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullpt…

中移动完成透镜天线远距覆盖和降本增效试点

日前,中国移动研究院在官微上正式发布了《新型透镜天线进行首次高铁覆盖实验》一文。中国移动研究院、中国移动甘肃公司与西安海天天线科技股份有限公司联合开展的人工介质圆柱透镜天线在高铁、高速等线状纵深领域的长距覆盖取得突破性进展。两年以来,铁…

基于PHPEnv的本地环境搭建—PHP第一个项目:HelloWorld(从安装到运行)

1、安装软件 编程工具:Notepad 运行环境:phpEnv 2、用phpEnv建立本地运行环境 (1)官方下载phpEnv,运行phpEnv,启动服务。服务启动之后,apache和mysql变绿。如下图所示: &#xff0…

在idae中为什么用Module创建一个新的Maven项目的时候会被卡死

一:问题描述 然后就会卡死, 二:问题解决 我们会发现这里的路径是有问题的,idea自带的maven会卡死我们,因为下载jar包的速度慢的惊人 将其改为我们自己maven路径,下载速度会很快,便不会出现卡死的现象&a…

ASP.NET Core Blazor Webassembly 之 数据绑定

上一次我们学习了Blazor组件相关的知识(Asp.net Core Blazor Webassembly - 组件)。这次继续学习Blazor的数据绑定相关的知识。当代前端框架都离不开数据绑定技术。数据绑定技术以数据为主导来驱动UI界面,用户对数据的修改会实时提现在UI上&a…

PHP做二次开发:本机安装ThinkCMF系统

使用工具:phpEnv、TortoiseGit 具体步骤: 1.获取thinkcmf源代码 2.修改Hosts文件设置虚拟域名指向本机 3.配置apache建立本地站点 4.建立数据库 5.访问本地站点开始安装 第一步:获取thinkcmf源代码 1.打开浏览器访问gitee.com,搜…

107. 二叉树的层序遍历 II and 102. 二叉树的层序遍历 023(BFS模板题打两道)

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullpt…

PHP做二次开发:ThinkCMF门户应用安装

使用工具:phpEnv 具体步骤: 1.获取门户应用portal源码 2.安装portal代码 3.执行portal数据库文件 4.安装并启用前台模板 5.导入后台管理菜单 第一步:获取门户应用portal源码 1.打开官方网站http://kancloud.cn/thinkcmf/faq/1005840&#xf…