使用Entity Framework Core管理数据库架构进行数据迁移

Posted JimCarter

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Entity Framework Core管理数据库架构进行数据迁移相关的知识,希望对你有一定的参考价值。

在实际项目中,数据模型随着功能的实现而变化:添加和删除新的实体或属性,并且需要相应地更改数据库架构,使其与应用程序保持同步。 EF Core 中的迁移功能能够以递增方式更新数据库架构,使其与应用程序的数据模型保持同步,同时保留数据库中的现有数据。

简要地说,迁移的方式如下:

  • 当引入数据模型更改时,开发人员使用 EF Core 工具添加相应的迁移,以描述使数据库架构保持同步所需的更新。EF Core 将当前模型与旧模型的快照进行比较,以确定差异,并生成迁移源文件;文件可在项目的源代码管理中进行跟踪,如任何其他源文件。
  • 生成新的迁移后,可通过多种方式将其应用于数据库。 EF Core 在一个特殊的历史记录表中记录所有应用的迁移,使其知道哪些迁移已应用,哪些迁移尚未应用。

迁移简单来说有两种方式:

  1. 粗暴方式:就是直接删库,多用于项目初始阶段。先调用Database.EnsureDeleted();,然后调用Database.EnsureCreated();。优点就是快,不啰嗦。缺点就是之前的数据全没了。
  2. 优雅方式:既可以更新表结构又可以保留数据库原有的数据。优雅迁移的过程就是先创建迁移记录,然后执行这个迁移记录来更新数据库。我们接下来会重点介绍这种方式。

1. 进行迁移

1.1 常用命令

首先熟悉几个常用的迁移命令。

命令作用
get-help about_entityframework提供EFCore的帮助信息,如果需要查看Add-Migration命令的具体信息,可以执行get-help Add-Migration
Add-Migration创建迁移记录
Update-Database执行迁移记录
Remove-Migration删除迁移
Get-Migration列出迁移

1.2 迁移过程

  1. 首先,安装nuget包Microsoft.EntityFrameworkCore.ToolsMicrosoft.EntityFrameworkCore.Design(包含了需要的迁移命令)。

  2. 然后,打开包管理器控制台,路径如下:

    打开之后就看到了命令窗口。

  3. 创建迁移记录,执行Add-Migration RecordXXXX命令(其中RecordXXX是迁移记录的名称,自己可以随便写),就可以看到资源管理器里多了一个Migrations文件夹,里面包含一些文件,这个文件夹的作用后续会介绍。

  4. 执行迁移记录:
    Update-Database用来执行迁移记录,执行完之后数据库接口就会变更。除了这个执行这个命令进行数据库变更外,还可以通过导出脚本的方式进行变更,后续会介绍。

  5. 此时就可以看到数据库已经响应了变更。而且数据库里多了一个表:


1.3 Migrations文件夹的作用

目录下有以下三个文件:

  • 20210812083634_MigraRecordAAA.cs:主迁移文件。 包含应用迁移所需的操作(在 Up 方法中)和还原迁移所需的操作(在 Down方法 中)。
  • 20210812083634_MigraRecordAAA.Designer.cs:迁移元数据文件。 包含 EF 所用的信息。
  • OpsDbContextModelSnapshot.cs:当前模型的快照。 用于确定添加下一迁移时的更改内容。

文件名中的时间戳有助于保证文件按时间顺序排列,以便你查看更改情况。

如果你不想把迁移记录放到默认的Migrations目录里,则创建迁移记录时,可以指定目录:Add-Migration MigrationBBBB -OutputDir AAA\\BBBB

1.4 自定义Migrations里的迁移代码

保险起见在执行迁移记录之前你应该浏览一遍生成的迁移代码,确保不会有问题。

1.4.1 列重命名

在重命名属性的时候,会导致列重命名。此项操作需要特别注意。如果将属性Name改为FullName,EF Core将默认会生成以下迁移操作:

migrationBuilder.DropColumn(
    name: "Name",
    table: "Customers");

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customers",
    nullable: true);

即删除了原有的列,然后又新增一列,这样会导致原有数据的丢失。所以应做如下调整:

migrationBuilder.RenameColumn(
    name: "Name",
    table: "Customers",
    newName: "FullName");

1.4.2 添加原始SQL

考虑这么一种情况:我们想把FirstNameLastName属性合并到一个新增的FullName上。EF Core就会这么生成语句:

migrationBuilder.DropColumn(
    name: "FirstName",
    table: "Customer");

migrationBuilder.DropColumn(
    name: "LastName",
    table: "Customer");

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customer",
    nullable: true);

这么一来也会导致数据丢失,所以需要手动编辑下这个文件,执行一段预操作:

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customer",
    nullable: true);

migrationBuilder.Sql(
@"
    UPDATE Customer
    SET FullName = FirstName + ' ' + LastName;
");

migrationBuilder.DropColumn(
    name: "FirstName",
    table: "Customer");

migrationBuilder.DropColumn(
    name: "LastName",
    table: "Customer");

注意:通常情况下如果执行迁移会导致数据丢失时,迁移工具会进行提醒,千万注意这个提醒。

2. 执行迁移

之前迁移除了上面我们说的Update-Database命令之外还可以生成迁移SQL脚本,然后将脚本交给DBA执行。

常见命令:

命令功能
Script-Migration生成一个从空白数据库到最新迁移的 SQL 脚本
Script-Migration AddNewTables生成一个从记录AddNewTables到最新的SQL脚本
Script-Migration RecordA RecordB生成一个从RecordA到RecordB的脚本,如果RecordA和RecordB顺序互换,则表示回滚
Script-Migration -Idempotent生成幂等迁移脚本

以上是关于使用Entity Framework Core管理数据库架构进行数据迁移的主要内容,如果未能解决你的问题,请参考以下文章

使用Entity Framework Core管理数据库架构进行数据迁移

使用 Key Vault 和包管理器控制台为 Entity Framework Core 连接和数据库迁移

使用 Entity Framework Core 更新相关数据

使用 ASP.NET Core 和 Entity Framework Core 进行集成测试 - 如何在每次测试时恢复数据库中的测试数据?

如何在 Entity Framework Core cli 工具中使用来自 dotnet 6 最小 API 的配置

entity framework core在独立类库下执行迁移操作