教程:第 5 部分,将迁移应用到 Contoso University 示例

在本教程中,你将开始使用 EF Core 迁移功能来管理数据模型更改。 在随后的教程中,随着数据模型的变化,你将添加更多的迁移。

在本教程中,你将:

  • 了解迁移
  • 创建初始迁移
  • 检查向上和向下方法
  • 了解数据模型快照
  • 执行迁移

Prerequisites

About migrations

开发新应用程序时,数据模型会频繁更改,每次模型更改时,它都会与数据库不同步。 你已启动这些教程,方法是将 Entity Framework 配置为创建数据库(如果不存在)。 然后,每次更改数据模型(添加、删除或更改实体类或更改 DbContext 类)时,都可以删除数据库,EF 会创建一个与模型匹配的新数据库,并使用测试数据对它进行种子设置。

在将应用程序部署到生产环境之前,使数据库与数据模型保持同步的方法非常有效。 当应用程序在生产环境中运行时,它通常存储要保留的数据,并且你不希望每次进行更改(例如添加新列)时丢失所有内容。 EF Core迁移功能通过使 EF 更新数据库架构而不是创建新数据库来解决此问题。

您可以使用包管理器控制台(PMC)或CLI来处理迁移。 这些教程演示如何使用 CLI 命令。 有关 PMC 的信息在 本教程结束时

删除数据库

将 EF Core 工具安装为 全局工具 并删除数据库。

dotnet tool install --global dotnet-ef
dotnet ef database drop

Note

默认情况下,要安装的 .NET 二进制文件的体系结构表示当前运行的 OS 体系结构。 若要指定不同的 OS 体系结构,请参阅 dotnet tool install, --arch option。 有关详细信息,请参阅 GitHub 问题 dotnet/AspNetCore.Docs #29262

以下部分介绍如何运行 CLI 命令。

创建初始迁移

保存更改并生成项目。 然后打开命令窗口并导航到项目文件夹。 这是一种快速完成的方法:

  • 解决方案资源管理器中,右键单击项目,然后从上下文菜单中选择 “在文件资源管理器中打开文件夹 ”。

    在“文件资源管理器”菜单项中打开

  • 在地址栏中输入“cmd”,然后按 Enter。

    打开命令窗口

在命令窗口中输入以下命令:

dotnet ef migrations add InitialCreate

在上述命令中,将显示类似于以下内容的输出:

info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core initialized 'SchoolContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
Done. To undo this action, use 'ef migrations remove'

如果看到错误消息“无法访问文件...ContosoUniversity.dll,因为它正被另一个进程使用。”,请在 Windows 系统托盘中找到 IIS Express 图标,然后右键单击它,然后单击 ContosoUniversity > Stop Site

分析向上和向下的方法

执行 migrations add 命令时,EF 生成了从头开始创建数据库的代码。 此代码位于“迁移”文件夹中,在名为<timestamp>_InitialCreate.cs的文件中。 类 Up 的方法 InitialCreate 创建与数据模型实体集对应的数据库表,该方法 Down 将删除它们,如以下示例所示。

public partial class InitialCreate : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Course",
            columns: table => new
            {
                CourseID = table.Column<int>(nullable: false),
                Credits = table.Column<int>(nullable: false),
                Title = table.Column<string>(nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Course", x => x.CourseID);
            });

        // Additional code not shown
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Enrollment");
        // Additional code not shown
    }
}

迁移调用 Up 该方法来实现迁移的数据模型更改。 输入用于回滚更新的命令时,迁移会调用该方法 Down

此代码适用于输入 migrations add InitialCreate 命令时创建的初始迁移。 迁移名称参数(示例中的“InitialCreate”)用于文件名,可以是所需的任何名称。 最好选择一个单词或短语来概括迁移中正在执行的动作。 例如,您可以将以后的迁移命名为“AddDepartmentTable”。

如果在数据库已存在时创建了初始迁移,则会生成数据库创建代码,但它不必运行,因为数据库已与数据模型匹配。 将应用部署到数据库尚不存在的另一个环境时,此代码将运行以创建数据库,因此最好先对其进行测试。 这就是为什么你之前删除了数据库 -- 以便迁移可以从头开始创建新的数据库。

数据模型快照

迁移会创建当前数据库架构的快照Migrations/SchoolContextModelSnapshot.cs。 添加迁移时,EF 通过将数据模型与快照文件进行比较来确定更改的内容。

使用 dotnet ef migrations remove 命令删除迁移。 dotnet ef migrations remove 删除迁移并确保快照正确重置。 如果 dotnet ef migrations remove 失败,则用于 dotnet ef migrations remove -v 获取有关失败的详细信息。

有关如何使用快照文件的详细信息,请参阅 EF Core 团队环境中的迁移

执行迁移

在命令窗口中,输入以下命令以在其中创建数据库和表。

dotnet ef database update

该命令的输出类似于 migrations add 该命令,只不过你会看到设置数据库的 SQL 命令的日志。 以下示例输出中省略了大多数日志。 如果不想在日志消息中看到此级别的详细信息,可以更改文件中的 appsettings.Development.json 日志级别。 有关详细信息,请参阅 .NET 中的日志记录和 ASP.NET Core

info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core initialized 'SchoolContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (274ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      CREATE DATABASE [ContosoUniversity2];
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (60ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      IF SERVERPROPERTY('EngineEdition') <> 5
      BEGIN
          ALTER DATABASE [ContosoUniversity2] SET READ_COMMITTED_SNAPSHOT ON;
      END;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (15ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE [__EFMigrationsHistory] (
          [MigrationId] nvarchar(150) NOT NULL,
          [ProductVersion] nvarchar(32) NOT NULL,
          CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
      );

<logs omitted for brevity>

info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
      VALUES (N'20190327172701_InitialCreate', N'5.0-rtm');
Done.

使用 SQL Server 对象资源管理器 检查数据库,就像第一个教程中所做的那样。 你将注意到添加了一个__EFMigrationsHistory表,用于跟踪哪些迁移已应用于数据库。 查看该表中的数据,你将看到第一个迁移的一行。 (上一个 CLI 输出示例中的最后一个日志显示创建此行的 INSERT 语句。

运行应用程序,验证所有内容是否仍与以前相同。

“学生索引”页

比较 CLI 和 PMC

用于管理迁移的 EF 工具可从 .NET CLI 命令或 Visual Studio 包管理器控制台 (PMC)窗口中的 PowerShell cmdlet 获取。 本教程演示如何使用 CLI,但如果需要,可以使用 PMC。

PMC 命令的 EF 命令位于 Microsoft.EntityFrameworkCore.Tools 包中。 此包包含在 Microsoft.AspNetCore.App 元包中,因此,如果你的应用具有 Microsoft.AspNetCore.App 的包引用,则无需添加包引用。

重要: 这与通过编辑 .csproj 文件为 CLI 安装的包不同。 此名称的结尾是Tools,不同于CLI包名称的结尾是Tools.DotNet

有关 CLI 命令的详细信息,请参阅 .NET CLI

有关 PMC 命令的详细信息,请参阅包管理器控制台(Visual Studio)。

获取代码

下载或查看已完成的应用程序。

Next step

转到下一教程,开始查看有关扩展数据模型的更高级主题。 在此过程中,你将创建并应用其他迁移。