如何部署实体框架数据库迁移

目录

通过应用迁移

最小特权的主体

通过生成服务器迁移

命令行工具

幂等SQL脚本

捆绑包​编辑

命令行应用程序

认证

总结


管理有状态数据通常是DevOps策略中较棘手的部分之一。实体框架的迁移功能可以极大地帮助其小型、独立可执行的、对PR友好的增量。从理论上讲,如果部署进展不佳,它甚至可以授予还原迁移的能力。如果使用得当,该技术可以带来巨大的帮助。

但是,在实践中,有很多不同的方法可以自动执行这些增量。每种方法都有优点和缺点,可能适用于一个项目的方法可能不适用于另一个项目。

在这篇文章中,我将展示运行EF数据库迁移的六种方法,说明每种方法在哪些情况下最有帮助,然后演示如何在从生成服务器运行迁移时设置Active DirectoryAD)身份验证并正确设置连接字符串。

通过应用迁移

何时运行迁移的问题是...有趣。问题是,当应用程序首次使用DbContext.Database.MigrateAsync()命令启动时,运行迁移非常容易。

在启动时运行迁移既方便又节省时间,因为它搭载了现有的数据库连接和防火墙规则。但它也有一些缺点:

  1. 减慢应用启动速度
  2. 难以还原
  3. 长时间运行的迁移的超时问题
  4. 违反最小特权原则

最后一点值得解释。它引用了以下安全最佳做法:

最小特权的主体

为了尽量减少安全事件造成的损害,应向系统授予所需的最低访问级别。

换句话说,不要向系统授予任何不需要的权限。

例如,作为日常操作的一部分,应用通常不需要删除数据库表,因此不应授予它们该权限。但是,这正是应用在运行数据库迁移时所需的权限类型。因此,通过让应用运行数据库迁移,我们无意中赋予攻击者造成比通过应用访问数据库所需的更多混乱的能力。

更具体地说:如果应用程序正在连接到SQL Server,则可以授予运行应用程序的帐户db_datareaderdb_datawriter,但不能是db_ddladmin,绝对不能是db_owner。这样做将在安全中心审核中生成一个标志。

通过生成服务器迁移

如果您仍在开发中,有意推迟安全风险,或者只是总体上对风险感到满意,则通过应用程序迁移可能已经足够了。但是,准备就绪后,另一种方法是让生成服务器运行EF迁移。有几种方法可以解决这个问题,每种方法都有优点和缺点。

命令行工具

作为开发人员,你可能已经熟悉dotnet ef数据库更新命令。此选项在DevOps世界中不方便,因为它需要源代码。由于各种原因,源代码是一种痛苦,其中最重要的是您需要获取您尝试运行的部署的确切代码版本。下面的其他方法通常更可取。

SQL脚本

如果让生成服务器运行命令dotnet ef migrations脚本[oldmigration] [newmigration],它将生成一个文件,你可以将其另存为生成管道中的项目,然后为每个环境执行。与其他一些选项不同,此方法生成可由DBA查看的资产。但是,确定哪些值用于旧迁移和新迁移将很棘手。更糟糕的是,如果每个环境都处于不同的版本,就像不是每个PR部署到生产环境时经常发生的那样,那么可能不可能生成适用于所有环境的单个项目,因为这些值对于每个环境都是不同的。因此,我通常不推荐这种方法。

幂等SQL脚本

幸运的是,如果将该--idempotent参数传递给dotnet ef迁移脚本,则它将生成一个脚本,该脚本将仅运行需要运行的迁移。生成的文件看起来像一堆if语句,如下所示:

BEGIN
    CREATE INDEX [IX_AbpAuditLogActions_AuditLogId] _
           ON [AbpAuditLogActions] ([AuditLogId]);
END;
GO

虽然此选项不授予还原错误部署的选项,但它非常适合作为已发布的构建工件,可以由DBA查看,并且在每个环境处于不同版本时工作。但是,此方法不是事务性的,因此迁移失败可能会使数据库处于不一致状态。

捆绑包

捆绑包很棒。它们解决了将事务应用于迁移的问题。只需让生成服务器运行dotnet ef迁移捆绑包--self-contained -r [linux-x64|win-x64],即可获得单个文件二进制文件(默认情况下称为 efbundle.exe),你可以将其发布为项目,在事务中运行迁移,并且仅运行需要应用的迁移。您甚至可以指定特定的迁移,从而可以还原迁移。生成的文件如下所示:E

Entity Framework Core Migrations Bundle 7.0.1

Usage: efbundle [arguments] [options] [[--] <arg>...]]

Arguments:
  <MIGRATION>  The target migration. If '0', all migrations will be reverted. 
  Defaults to the last migration.

Options:
  --connection <CONNECTION>  The connection string to the database. 
    Defaults to the one specified in AddDbContext or OnConfiguring.
  --version                  Show version information
  -h|--help                  Show help information
  -v|--verbose               Show verbose output.
  --no-color                 Don't colorize output.
  --prefix-output            Prefix output with level.</span></code>

这个选项几乎是我的最爱。它唯一缺少的是能够在迁移之外运行自定义代码。

命令行应用程序

曾几何时,我的一个项目将加密数据存储在数据库的字段中。在我们投入生产后(当然),我们意识到加密算法太强了,导致了性能问题。我们需要降低加密的强度,但这意味着我们需要执行涉及用C#编写的方法的复杂数据迁移。

我们必须运行一个查询来读取每一行,使用C#中的旧算法对其进行解密,使用C#中的新算法重新加密它,然后将其更新回数据库中。对于EF迁移来说应该足够简单吧?

令人惊讶的是,事实证明EF迁移无法完成此类工作。它们旨在运行insertupdate SQL语句或createdrop DDL语句,但不检索数据。自己检查一下:看看是否可以在MigrationBuilder上找到一种检索数据的单一方法。

因此,由于该算法位于C#方法中,并且由于EF迁移无法访问它,因此我们必须在EF迁移之外运行代码。

幸运的是, 因为我们使用的是ASP.NET BoilerplateABP框架的前身),它包含一个运行我们迁移的命令行应用程序.这提供了在迁移之前或之后运行代码的灵活性,从而解决了我们的问题。

从生成服务器运行DbContext.Database.MigrateAsync()的命令行应用(或带有命令行选项的主应用)可以在事务中运行,并且使用--self-contained -r [linux-x64|win-x64]编译时使用几乎是单个文件(必须包含 Microsoft.Data.SqlClient.SNI.dll)。缺点是它们不允许还原迁移。但是,它们是我个人的最爱,因为它们在面对艰难的迁移时提供了最大的灵活性。此外,它们在每租户数据库多租户方案中特别有效。

如果您对此方法的详细信息感兴趣,请查看我创建的 DbMigrator示例项目,该项目在多阶段生成管道的一个阶段编译和发布命令行应用,然后在另一个阶段执行它。

认证

是时候承认房间里的大象了。如果不在应用启动时运行迁移,如何从生成服务器获取与数据库的连接?此外,假设你在Azure上使用SQL Server,并遵循仅使用AD身份验证的最佳做法,如何在无外设环境中使用Active Directory帐户进行身份验证?

一般来说,有四个步骤。首先,创建应用注册。其次,使用CREATE USER [{userName}] FROM EXTERNAL PROVIDER;将应用程序注册添加到数据库,并使用EXEC sp_addrolemember 'ddl_admin', '{userName}'授予其运行DDL的权限。第三,为应用注册创建一个机密:

最后,添加防火墙规则以允许从自定义生成代理访问数据库,或者,如果使用的是托管代理,则添加Allow Azure services and resources to access this server,在 Bicep 中如下所示:

resource firewallRule_AzureIps 'Microsoft.Sql/servers/firewallRules@2021-11-01' = {
  name: 'AllowAzureIps'
  parent: sql
  properties: {
    startIpAddress: '0.0.0.0'
    endIpAddress: '0.0.0.0'
  }
}

最后,您应该能够使用如下所示的连接字符串:"Server=tcp:{sqlServerName}.database.windows.net,1433; "Database={dbName}; Encrypt=True; User Id={servicePrincipalAppId}; Password={servicePrinicpalSecret}; Authentication='Active Directory Service Principal';"

仅此而已。输入应用注册应用ID和生成的机密,即可开始比赛。

总结

在本文中,我讨论了运行迁移的六种方法,并随后介绍了如何完成身份验证。下表将有助于总结优缺点:

正如我所提到的,我个人最喜欢的是最后一个命令行应用,因为即使它不支持自动还原,它也将在事务中运行,并且可以灵活地在EF之外执行复杂的迁移。

您尝试过哪些方法?我错过了什么吗?随意在评论中插话。

本文最初发表于 http://www.leerichardson.com/feeds/posts/default

https://www.codeproject.com/Articles/5355897/How-to-Deploy-Entity-Framework-Database-Migrations

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
.NET Core实体框架(Entity Framework Core)是一个用于.NET Core平台的对象关系映射(ORM)框架,它提供了一种简化数据库访问和操作的方式。下面是对.NET Core实体框架的介绍: 1. 数据库上下文(DbContext):数据库上下文是.NET Core实体框架的核心组件之一,它表示与数据库的会话,并提供了对数据库的访问和操作。通过定义派生自DbContext的类,可以创建数据库上下文对象,并在其中定义实体集和数据库表之间的映射关系。 2. 实体类(Entity Class):实体类是代表数据库表的.NET类。通过定义实体类,可以将数据库表中的每一行数据映射到一个对象实例上。实体类通常包含属性来表示表中的列,并且可以定义关系属性来表示表之间的关联关系。 3. 数据迁移(Data Migration):数据迁移是.NET Core实体框架中的一个重要特性,它允许开发人员对数据库模式进行版本控制和管理。通过使用数据迁移,可以轻松地在应用程序的开发过程中对数据库模式进行更改,并将这些更改应用到目标数据库中。 4. LINQ查询(LINQ Query):.NET Core实体框架支持使用LINQ(Language Integrated Query)进行数据查询。通过使用LINQ查询,可以以面向对象的方式编写数据库查询语句,而无需直接编写SQL语句。 5. 数据库提供程序(Database Provider):.NET Core实体框架支持多种数据库提供程序,包括Microsoft SQL Server、MySQL、SQLite等。通过选择适当的数据库提供程序,可以与不同类型的数据库进行交互。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值