迁移概述Migrations Overview

在实际项目中,数据模型随着功能的实现而变化:添加和删除新的实体或属性,并且需要相应地更改数据库架构,使其与应用程序保持同步。In real world projects, data models change as features get implemented: new entities or properties are added and removed, and database schemas needs to be changed accordingly to be kept in sync with the application. EF Core 中的迁移功能能够以递增方式更新数据库架构,使其与应用程序的数据模型保持同步,同时保留数据库中的现有数据。The migrations feature in EF Core provides a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database.

简要地说,迁移的方式如下:At a high level, migrations function in the following way:

  • 当引入数据模型更改时,开发人员使用 EF Core 工具添加相应的迁移,以描述使数据库架构保持同步所需的更新。EF Core 将当前模型与旧模型的快照进行比较,以确定差异,并生成迁移源文件;文件可在项目的源代码管理中进行跟踪,如任何其他源文件。When a data model change is introduced, the developer uses EF Core tools to add a corresponding migration describing the updates necessary to keep the database schema in sync. EF Core compares the current model against a snapshot of the old model to determine the differences, and generates migration source files; the files can be tracked in your project's source control like any other source file.
  • 生成新的迁移后,可通过多种方式将其应用于数据库。Once a new migration has been generated, it can be applied to a database in various ways. EF Core 在一个特殊的历史记录表中记录所有应用的迁移,使其知道哪些迁移已应用,哪些迁移尚未应用。EF Core records all applied migrations in a special history table, allowing it to know which migrations have been applied and which haven't.

本页的其余部分是使用迁移的分步式入门指南。The rest of this page is a step-by-step beginner's guide for using migrations. 有关更深入的信息,请参阅本节中的其他页面。Consult the other pages in this section for more in-depth information.

入门Getting started

假设你刚刚完成了第一个 EF Core 应用程序,其中包含以下简单模型:Let's assume you've just completed your first EF Core application, which contains the following simple model:

public class Blog
    public int Id { get; set; }
    public string Name { get; set; }

在开发过程中,你可能已使用创建和删除 API 以快速迭代,并根据需要更改模型;但现在,你的应用程序将进入生产环境,你需要一种方法来安全地演化架构,而无需删除整个数据库。During development, you may have used the Create and Drop APIs to iterate quickly, changing your model as needed; but now that your application is going to production, you need a way to safely evolve the schema without dropping the entire database.

安装工具Install the tools

首先,必须安装 EF Core 命令行工具First, you'll have to install the EF Core command-line tools:

创建第一个迁移Create your first migration

你现在已准备好添加第一个迁移!You're now ready to add your first migration! 指示 EF Core 创建名为 InitialCreate 的迁移:Instruct EF Core to create a migration named InitialCreate:

dotnet ef migrations add InitialCreate

EF Core 将在项目中创建一个名为“Migrations”的目录,并生成一些文件。EF Core will create a directory called Migrations in your project, and generate some files. 最好检查 EF Core 生成的内容,并在可能的情况下修改它,但现在我们跳过此操作。It's a good idea to inspect what exactly EF Core generated - and possibly amend it - but we'll skip over that for now.

创建数据库和架构Create your database and schema

此时,可以让 EF 创建数据库并从迁移中创建架构。At this point you can have EF create your database and create your schema from the migration. 可以通过以下操作实现这一点:This can be done via the following:

dotnet ef database update

就是这么回事 - 你的应用程序已准备好在新数据库上运行,你无需编写任何 SQL 代码。That's all there is to it - your application is ready to run on your new database, and you didn't need to write a single line of SQL. 请注意,这种应用迁移的方法非常适合本地开发,但不太适用于生产环境 - 有关详细信息,请参阅应用迁移页面Note that this way of applying migrations is ideal for local development, but is less suitable for production environments - see the Applying Migrations page for more info.

发展模型Evolving your model

几天后,系统会要求你将创建时间戳添加到博客。A few days have passed, and you're asked to add a creation timestamp to your blogs. 你已完成针对应用程序的必要更改,模型现在如下所示:You've done the necessary changes to your application, and your model now looks like this:

public class Blog
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime CreatedTimestamp { get; set; }

模型和生产数据库现在不同步,我们必须向数据库架构中添加一个新列。Your model and your production database are now out of sync - we must add a new column to your database schema. 让我们为此创建新迁移:Let's create a new migration for this:

dotnet ef migrations add AddBlogCreatedTimestamp

请注意,我们为迁移提供了一个描述性名称,以便以后更容易了解项目历史记录。Note that we give migrations a descriptive name, to make it easier to understand the project history later.

由于这不是项目的第一次迁移,EF Core 现在会在添加列之前将更新的模型与旧模型的快照进行比较;模型快照是 EF Core 在你添加迁移时生成的文件之一,并签入到源代码管理中。Since this isn't the project's first migration, EF Core now compares your updated model against a snapshot of the old model, before the column was added; the model snapshot is one of the files generated by EF Core when you add a migration, and is checked into source control. 基于该比较,EF Core 检测到已添加一列,并添加适当的迁移。Based on that comparison, EF Core detects that a column has been added, and adds the appropriate migration.

现在,你可以像以前一样应用迁移:You can now apply your migration as before:

dotnet ef database update

请注意,这次 EF 检测到数据库已存在。Note that this time, EF detects that the database already exists. 此外,在之前第一次应用迁移时,此事实记录在数据库中的特殊迁移历史记录表中;这允许 EF 自动仅应用新的迁移。In addition, when our first migration was applied above, this fact was recorded in a special migrations history table in your database; this allows EF to automatically apply only the new migration.

排除模型的各个部分Excluding parts of your model


EF Core 5.0 中已引入此功能。This feature was introduced EF in Core 5.0.

有时,你可能希望引用其他 DbContext 中的类型。Sometimes you may want to reference types from another DbContext. 这可能会导致迁移冲突。This can lead to migration conflicts. 若要防止出现这种情况,请从 DbContext 之一的迁移中排除该类型。To prevent this, exclude the type from the migrations of one of the DbContexts.

protected override void OnModelCreating(ModelBuilder modelBuilder)
        .ToTable("AspNetUsers", t => t.ExcludeFromMigrations());

后续步骤Next steps

以上只是迁移的简短简介。The above was only a brief introduction to migrations. 请参阅其他文档页面,详细了解如何管理迁移应用迁移等。Please consult the other documentation pages to learn more about managing migrations, applying them, and other aspects. .NET Core CLI 工具参考还包含有关不同命令的有用信息The .NET Core CLI tool reference also contains useful information on the different commands

其他资源Additional resources