教學課程:使用移轉功能 - ASP.NET MVC 搭配 EF CoreTutorial: Using the migrations feature - ASP.NET MVC with EF Core

在本教學課程中,您會先使用 EF Core 移轉功能來管理資料模型變更。In this tutorial, you start using the EF Core migrations feature for managing data model changes. 在稍後的教學課程中,您將在變更資料模型時新增更多移轉作業。In later tutorials, you'll add more migrations as you change the data model.

在本教學課程中,您已:In this tutorial, you:

  • 了解移轉Learn about migrations
  • 變更連接字串Change the connection string
  • 建立初始移轉Create an initial migration
  • 檢查 Up 和 Down 方法Examine Up and Down methods
  • 了解資料模型快照集Learn about the data model snapshot
  • 套用移轉Apply the migration

必要條件Prerequisites

關於移轉About migrations

在開發新的應用程式時,您的資料模型會頻繁變更,而每次模型變更時,模型會與資料庫不同步。When you develop a new application, your data model changes frequently, and each time the model changes, it gets out of sync with the database. 首先,您會設定 Entity Framework 以建立資料庫 (如果尚未存在的話) 以進行本教學課程。You started these tutorials by configuring the Entity Framework to create the database if it doesn't exist. 然後在每次變更資料模型 (新增、移除或變更實體類別或變更您的 DbContext 類別) 時,您可以刪除資料庫,EF 即會建立一個相符的新模型,並植入測試資料。Then each time you change the data model -- add, remove, or change entity classes or change your DbContext class -- you can delete the database and EF creates a new one that matches the model, and seeds it with test data.

在您將應用程式部署到生產環境之前,都可以使用上述方法讓資料庫與資料模型保持同步。This method of keeping the database in sync with the data model works well until you deploy the application to production. 但當應用程式在生產環境中執行時,通常會儲存您想要保留的資料,而您也不想在每次資料變更 (例如新增資料行) 時遺失任何項目。When the application is running in production it's usually storing data that you want to keep, and you don't want to lose everything each time you make a change such as adding a new column. 為了解決上述問題,EF Core 移轉功能可讓 EF 更新資料庫結構描述,而不是建立新的資料庫。The EF Core Migrations feature solves this problem by enabling EF to update the database schema instead of creating a new database.

您可以使用套件管理員主控台 (PMC) 或命令列介面 (CLI),來進行移轉作業。To work with migrations, you can use the Package Manager Console (PMC) or the command-line interface (CLI). 這些教學課程會示範如何使用 CLI 命令。These tutorials show how to use CLI commands. PMC 的資訊位於本教學課程結尾Information about the PMC is at the end of this tutorial.

變更連接字串Change the connection string

appsettings.json 檔案中,將連接字串中的資料庫名稱變更為 ContosoUniversity2 (或您所使用之電腦上未用過的其他名稱)。In the appsettings.json file, change the name of the database in the connection string to ContosoUniversity2 or some other name that you haven't used on the computer you're using.

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=ContosoUniversity2;Trusted_Connection=True;MultipleActiveResultSets=true"
  },

這項變更會設定專案,以讓第一次移轉建立新的資料庫。This change sets up the project so that the first migration will create a new database. 即使不採取上述動作,仍可開始進行移轉作業,但稍後您會了解這麼做的好處何在。This isn't required to get started with migrations, but you'll see later why it's a good idea.

注意

如果您不想變更資料庫名稱,替代方法是刪除資料庫。As an alternative to changing the database name, you can delete the database. 使用 [SQL Server 物件總管] (SSOX) 或 database drop CLI 命令:Use SQL Server Object Explorer (SSOX) or the database drop CLI command:

dotnet ef database drop

下節說明如何執行 CLI 命令。The following section explains how to run CLI commands.

建立初始移轉Create an initial migration

儲存您的變更,並建置專案。Save your changes and build the project. 接著,開啟命令視窗並巡覽至專案資料夾。Then open a command window and navigate to the project folder. 以下是執行這個動作的快速方法:Here's a quick way to do that:

  • 在 [方案總管] 中,於專案上按一下滑鼠右鍵,然後從操作功能表中選擇 [在檔案總管中開啟資料夾]。In Solution Explorer, right-click the project and choose Open Folder in File Explorer from the context menu.

    [在檔案總管中開啟] 功能表項目

  • 在位址列中輸入 "cmd",然後按 Enter。Enter "cmd" in the address bar and press Enter.

    開啟命令視窗

在命令視窗中輸入下列命令:Enter the following command in the command window:

dotnet ef migrations add InitialCreate

在命令視窗中,您會看到類似如下的輸出:You see output like the following in the command window:

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" 的可執行檔」,請參閱這篇部落格文章以取得疑難排解說明。If you see an error message No executable found matching command "dotnet-ef", see this blog post for help troubleshooting.

如果您看到錯誤訊息:「無法存取檔案...ContosoUniversity.dll,因為其他處理序正在使用此檔案。」請在 Windows 系統匣中尋找 IIS Express 圖示,以滑鼠右鍵按一下它,然後按一下 [ContosoUniversity] > [停止網站]。If you see an error message "cannot access the file ... ContosoUniversity.dll because it is being used by another process.", find the IIS Express icon in the Windows System Tray, and right-click it, then click ContosoUniversity > Stop Site.

檢查 Up 和 Down 方法Examine Up and Down methods

當您執行 migrations add 命令時,EF 產生的程式碼會從頭開始建立資料庫。When you executed the migrations add command, EF generated the code that will create the database from scratch. 您可以在 Migrations 資料夾,名為 <時間戳記>_InitialCreate.cs 的檔案中,找到這個程式碼。This code is in the Migrations folder, in the file named <timestamp>_InitialCreate.cs. InitialCreate 類別的 Up 方法會建立對應至資料模型實體集的資料庫資料表,而 Down 方法則會刪除它們,如下列範例所示。The Up method of the InitialCreate class creates the database tables that correspond to the data model entity sets, and the Down method deletes them, as shown in the following example.

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
    }
}

Migrations 會呼叫 Up 方法,以實作移轉所需的資料模型變更。Migrations calls the Up method to implement the data model changes for a migration. 當您輸入命令以復原更新時,Migrations 會呼叫 Down 方法。When you enter a command to roll back the update, Migrations calls the Down method.

這個程式碼適用於您之前輸入 migrations add InitialCreate 命令時所建立的初始移轉。This code is for the initial migration that was created when you entered the migrations add InitialCreate command. 移轉名稱參數 (在此範例中為 "InitialCreate") 可作為檔案名稱,您也可以任意命名。The migration name parameter ("InitialCreate" in the example) is used for the file name and can be whatever you want. 建議您選擇某個單字或片語,以摘要說明移轉中所要完成的作業。It's best to choose a word or phrase that summarizes what is being done in the migration. 例如,您可以將稍後的移轉命名為 "AddDepartmentTable"。For example, you might name a later migration "AddDepartmentTable".

如果在您建立初始移轉時資料庫已經存在,系統會產生資料庫建立程式碼,但不需要執行,因為資料庫已經符合資料模型。If you created the initial migration when the database already exists, the database creation code is generated but it doesn't have to run because the database already matches the data model. 當您將應用程式部署到資料庫尚未存在的其他環境中時,即會執行這個程式碼以建立您的資料庫;建議您先進行測試。When you deploy the app to another environment where the database doesn't exist yet, this code will run to create your database, so it's a good idea to test it first. 這就是為什麼稍早要您變更連接字串中資料庫名稱的原因,這樣一來,移轉即可從頭建立一個資料庫。That's why you changed the name of the database in the connection string earlier -- so that migrations can create a new one from scratch.

資料模型快照集The data model snapshot

移轉會在 Migrations/SchoolContextModelSnapshot.cs 中建立目前資料庫結構描述的「快照集」。Migrations creates a snapshot of the current database schema in Migrations/SchoolContextModelSnapshot.cs. 當您新增移轉時,EF 會比較資料模型與快照集檔案,以判斷變更的內容。When you add a migration, EF determines what changed by comparing the data model to the snapshot file.

刪除移轉時,請使用 dotnet ef migrations remove 命令。When deleting a migration, use the dotnet ef migrations remove command. dotnet ef migrations remove 會刪除移轉,並確保正確地重設快照集。dotnet ef migrations remove deletes the migration and ensures the snapshot is correctly reset.

如需如何使用快照集檔案的詳細資訊,請參閱小組環境中的 EF Core 移轉See EF Core Migrations in Team Environments for more information about how the snapshot file is used.

套用移轉Apply the migration

在命令視窗中輸入下列命令,以建立資料庫和其中的資料表。In the command window, enter the following command to create the database and tables in it.

dotnet ef database update

此命令的輸出類似於 migrations add 命令,不同之處在於其會顯示設定資料庫之 SQL 命令的記錄。The output from the command is similar to the migrations add command, except that you see logs for the SQL commands that set up the database. 下列範例輸出中省略了大部分的記錄。Most of the logs are omitted in the following sample output. 如果您不想看到這麼詳細的記錄訊息,可以變更 appsettings.Development.json 檔案中的記錄層級。If you prefer not to see this level of detail in log messages, you can change the log level in the appsettings.Development.json file. 如需詳細資訊,請參閱ASP.NET Core 中的記錄For more information, see 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 物件總管] 檢查資料庫。Use SQL Server Object Explorer to inspect the database as you did in the first tutorial. 您會發現新增 __EFMigrationsHistory 資料表,其會持續追蹤哪些移轉已套用至資料庫。You'll notice the addition of an __EFMigrationsHistory table that keeps track of which migrations have been applied to the database. 檢視該資料表中的資料,您會看到其中一個資料列代表第一個移轉。View the data in that table and you'll see one row for the first migration. (上述 CLI 輸出範例中的最後一則記錄會顯示建立此資料列的 INSERT 陳述式。)(The last log in the preceding CLI output example shows the INSERT statement that creates this row.)

執行應用程式,以驗證一切如往常般運作。Run the application to verify that everything still works the same as before.

Students [索引] 頁面

比較 CLI 與 PMCCompare CLI and PMC

您可以透過 .NET Core CLI 命令或 Visual Studio [套件管理員主控台] (PMC) 視窗中的 PowerShell Cmdlet,取得適用於管理移轉的 EF 工具。The EF tooling for managing migrations is available from .NET Core CLI commands or from PowerShell cmdlets in the Visual Studio Package Manager Console (PMC) window. 本教學課程示範如何使用 CLI,但是您也可以視習慣使用 PMC。This tutorial shows how to use the CLI, but you can use the PMC if you prefer.

適用於 PMC 命令的 EF 命令位於 Microsoft.EntityFrameworkCore.Tools 套件中。The EF commands for the PMC commands are in the Microsoft.EntityFrameworkCore.Tools package. 此套件包含在 Microsoft.AspNetCore.App metapackage 中;因此,如果您的應用程式具有 Microsoft.AspNetCore.App 的套件參考,則您不需要新增套件參考。This package is included in the Microsoft.AspNetCore.App metapackage, so you don't need to add a package reference if your app has a package reference for Microsoft.AspNetCore.App.

重要: 此套件與您透過編輯 .csproj 檔案為 CLI 安裝的套件不同。Important: This isn't the same package as the one you install for the CLI by editing the .csproj file. 這個套件的名稱以 Tools 結尾,不同於以 Tools.DotNet 結尾的 CLI 套件名稱。The name of this one ends in Tools, unlike the CLI package name which ends in Tools.DotNet.

如需 CLI 命令的詳細資訊,請參閱 .NET Core CLIFor more information about the CLI commands, see .NET Core CLI.

如需 PMC 命令的詳細資訊,請參閱套件管理員主控台 (Visual Studio)For more information about the PMC commands, see Package Manager Console (Visual Studio).

取得程式碼Get the code

下載或檢視已完成的應用程式。Download or view the completed application.

後續步驟Next step

在本教學課程中,您已:In this tutorial, you:

  • 了解移轉Learned about migrations
  • 了解 NuGet 移轉套件Learned about NuGet migration packages
  • 變更連接字串Changed the connection string
  • 建立初始移轉Created an initial migration
  • 檢查 Up 和 Down 方法Examined Up and Down methods
  • 了解資料模型快照集Learned about the data model snapshot
  • 套用移轉Applied the migration

若要開始查看更進階的主題,了解資料模型的擴展,請前往下一個教學課程。Advance to the next tutorial to begin looking at more advanced topics about expanding the data model. 在過程中,您會建立並套用其他移轉。Along the way you'll create and apply additional migrations.