本教程使用 EF Core 迁移功能管理数据模型更改。 后续教程将在更改数据模型时添加更多迁移。
在本教程中,你将了解:
开发新应用程序时,数据模型会频繁更改。每当模型更改时,模型都无法与数据库保持同步。 本系列教程首先配置 Entity Framework 以创建数据库(如果不存在)。 之后,每当更改数据模型(添加、删除或更改实体类或更改 DbContext 类)时,你都可以删除数据库,EF 将创建匹配该模型的新数据库并用测试数据为其设定种子。
这种使数据库与数据模型保持同步的方法适用于多种情况,但将应用程序部署到生产环境的情况除外。 当应用程序在生产环境中运行时,它通常会存储要保留的数据,以便不会在每次更改(如添加新列)时丢失所有数据。 EF Core 迁移功能可通过使 EF 更新数据库 架构而不是创建新数据库来解决此问题。
要使用迁移,可使用“包管理器控制台”(PMC) 或 CLI 。 以下教程演示如何使用 CLI 命令。 有关 PMC 的信息,请转到本教程末尾。
在 appsettings.json 文件中,将连接字符串中的数据库的名称更改为 ContosoUniversity2 或正在使用的计算机上未使用过的其他名称。
{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=ContosoUniversity2;Trusted_Connection=True;MultipleActiveResultSets=true" },
此更改将设置项目,以便初始迁移创建新的数据库。 这并不是开始使用迁移的必要操作,但稍后你便会了解这样做的好处。
备注
除更改数据库名称外,删除数据库同样可行。 使用 SQL Server 对象资源管理器 (SSOX) 或 database drop
CLI 命令:
dotnet ef database drop
下面的部分说明如何运行 CLI 命令。
保存更改并生成项目。 然后打开命令窗口并导航到项目文件夹。 下面是执行此操作的快速方法:
在解决方案资源管理器中,右键单击项目,然后从上下文菜单中选择“在文件资源管理器中打开文件夹”。
在地址栏中输入“cmd”,然后按 Enter。
在命令窗口中输入以下命令:
dotnet ef migrations add InitialCreate
命令窗口中出现如下输出:
info: Microsoft.EntityFrameworkCore.Infrastructure[10403] Entity Framework Core 2.2.0-rtm-35687 initialized 'SchoolContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None Done. To undo this action, use 'ef migrations remove'
备注
如果出现错误消息“找不到任何匹配 "dotnet-ef" 命令的可执行文件”,请参阅此博客文章获取故障排除帮助。
如果看到错误消息“无法访问文件...ContosoUniversity.dll,因为它正被另一个进程使用。”,请在 Windows 系统托盘中找到 IIS Express 图标并右键单击,然后单击“ContosoUniversity”>“停止站点”。
执行 migrations add
命令时,EF 已生成将用于从头创建数据库的代码。 此代码位于“Migrations”文件夹中名为 <timestamp>_InitialCreate.cs 的文件中。 InitialCreate
类的 Up
的方法将创建与数据模型实体集相对应的数据库表,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 Core 和 ASP.NET Core 中的日志记录。
info: Microsoft.EntityFrameworkCore.Infrastructure[10403] Entity Framework Core 2.2.0-rtm-35687 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'2.2.0-rtm-35687'); Done.
使用 SQL Server 对象资源管理器检查数据库(与第一个教程中的做法相同)。 你会发现添加了 __EFMigrationsHistory 表,该表可用于跟踪已应用到数据库的迁移。 查看该表中的数据,其中显示对应初始迁移的一行数据。 (上面的 CLI 输出示例中最后部分的日志显示了创建此行的 INSERT 语句。)
运行应用程序以验证所有内容照旧运行。
可通过 .NET Core CLI 命令或 Visual Studio 包管理器控制台 (PMC) 窗口中的 PowerShell cmdlet 使用可管理迁移的 EF 工具。 本教程演示如何使用 CLI,但也可以根据喜好使用 PMC。
适用于 PMC 命令的 EF 命令位于 Microsoft.EntityFrameworkCore.Tools 程序包中。 此包包含在 Microsoft.AspNetCore.App 元包中,因此,如果应用具有对 Microsoft.AspNetCore.App
的包引用,则无需添加包引用。
重要提示: 此包与通过编辑 .csproj 文件为 CLI 安装的包不同。 此程序包的名称以 Tools
结尾,而 CLI 程序包的名称以 Tools.DotNet
结尾。
有关 CLI 命令的详细信息,请参阅 .NET Core CLI。
有关 PMC 命令的详细信息,请参阅包管理器控制台 (Visual Studio)。
在本教程中,你将了解:
请继续阅读下一篇教程,开始了解有关展开数据模型的更高级主题。 同时还将介绍创建并应用其他迁移的方法。