移轉Migrations

資料模型在開發期間變更,而且與資料庫不同步。A data model changes during development and gets out of sync with the database. 您可以卸除資料庫,然後讓 EF 建立符合模型的新資料庫,但此程序會導致資料遺失。You can drop the database and let EF create a new one that matches the model, but this procedure results in the loss of data. 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.

移轉包含命令列工具和 API,可協助執行下列工作:Migrations includes command-line tools and APIs that help with the following tasks:

安裝工具Install the tools

安裝命令列工具Install the command-line tools:

建立移轉Create a migration

在您定義起始模型之後,即可開始建立資料庫。After you've defined your initial model, it's time to create the database. 若要新增初始移轉,請執行下列命令。To add an initial migration, run the following command.

Add-Migration InitialCreate
dotnet ef migrations add InitialCreate

會新增三個檔案到您移轉目錄下的專案:Three files are added to your project under the Migrations directory:

  • 00000000000000_InitialCreate.cs - 主要移轉檔案。00000000000000_InitialCreate.cs--The main migrations file. 包含套用移轉 (在 Up() 中) 及予以反轉 (在 Down() 中) 的必要作業。Contains the operations necessary to apply the migration (in Up()) and to revert it (in Down()).
  • 00000000000000_InitialCreate.Designer.cs - 移轉中繼資料檔案。00000000000000_InitialCreate.Designer.cs--The migrations metadata file. 包含 EF 使用的資訊。Contains information used by EF.
  • MyContextModelSnapshot.cs - 您目前模型的快照集。MyContextModelSnapshot.cs--A snapshot of your current model. 用來決定新增下一個移轉時所要變更的項目。Used to determine what changed when adding the next migration.

檔案名稱中的時間戳記有助於使其依時間先後順序排列,以便您查看變更的進展。The timestamp in the filename helps keep them ordered chronologically so you can see the progression of changes.

提示

您可以自由移動移轉檔案和變更其命名空間。You are free to move Migrations files and change their namespace. 新的移轉會作為最後一個移轉的同層級建立。New migrations are created as siblings of the last migration.

更新資料庫Update the database

接下來,將移轉套用到資料庫以建立結構描述。Next, apply the migration to the database to create the schema.

Update-Database
dotnet ef database update

自訂移轉程式碼Customize migration code

對您的 EF Core 模型進行變更後,資料庫結構描述會失去同步。若要將其更新為最新狀態,請新增另一個移轉。After making changes to your EF Core model, the database schema might be out of sync. To bring it up to date, add another migration. 您能夠以類似版本控制系統中認可訊息的方式來使用移轉名稱。The migration name can be used like a commit message in a version control system. 例如,如果變更是要檢閱的新實體類別,您可以選擇像是 AddProductReviews 的名稱。For example, you might choose a name like AddProductReviews if the change is a new entity class for reviews.

Add-Migration AddProductReviews
dotnet ef migrations add AddProductReviews

一旦建立移轉 (為其產生程式碼) 後,請檢閱程式碼的正確性,以及視需要新增、移除或修改任何作業,以便正確套用。Once the migration is scaffolded (code generated for it), review the code for accuracy and add, remove or modify any operations required to apply it correctly.

例如,移轉可能包含下列作業:For example, a migration might contain the following operations:

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

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

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

雖然這些作業會使資料庫結構描述符合規範,但不會保存現有的客戶名稱。While these operations make the database schema compatible, they don't preserve the existing customer names. 若要加以改善,請以下列格式重寫。To make it better, rewrite it as follows.

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

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

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

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

提示

當作業可能導致資料遺失時 (例如卸除資料行),移轉建立程序會引發警告。The migration scaffolding process warns when an operation might result in data loss (like dropping a column). 如果您看到該警告,請務必檢閱移轉程式碼的正確性。If you see that warning, be especially sure to review the migrations code for accuracy.

使用適當的命令將移轉套用到資料庫。Apply the migration to the database using the appropriate command.

Update-Database
dotnet ef database update

空白的移轉Empty migrations

新增移轉而不進行任何模型變更有時很實用。Sometimes it's useful to add a migration without making any model changes. 在這種情況下,新增移轉會建立具有空白類別的程式碼檔案。In this case, adding a new migration creates code files with empty classes. 您可以自訂此移轉來自訂未與 EF Core 模型直接相關的作業。You can customize this migration to perform operations that don't directly relate to the EF Core model. 您可能會想要以這種方式處理的項目如下:Some things you might want to manage this way are:

  • 全文檢索搜尋Full-Text Search
  • 函式Functions
  • 預存程序Stored procedures
  • 觸發程序Triggers
  • 檢視Views

移除移轉Remove a migration

在您新增移轉時,有時候會發現您必須在套用 EF Core 模型之前對其進行其他變更。Sometimes you add a migration and realize you need to make additional changes to your EF Core model before applying it. 若要移除上一個移轉,請使用此命令。To remove the last migration, use this command.

Remove-Migration
dotnet ef migrations remove

移除移轉後,您可以進行其他模型變更並再次予以新增。After removing the migration, you can make the additional model changes and add it again.

還原移轉Revert a migration

若您已經套用移轉 (或多個移轉) 到資料庫但需要還原,您可以使用相同命令來套用移轉,但必須指定所要復原到的移轉名稱。If you already applied a migration (or several migrations) to the database but need to revert it, you can use the same command to apply migrations, but specify the name of the migration you want to roll back to.

Update-Database LastGoodMigration
dotnet ef database update LastGoodMigration

產生 SQL 指令碼Generate SQL scripts

對移轉進行偵錯或將其部署到生產資料庫時,產生 SQL 指令碼很實用。When debugging your migrations or deploying them to a production database, it's useful to generate a SQL script. 您可以進一步檢閱程式碼的精確度,並對其進行微調以符合生產資料庫的需求。The script can then be further reviewed for accuracy and tuned to fit the needs of a production database. 指令碼也可以搭配部署技術使用。The script can also be used in conjunction with a deployment technology. 基本命令如下。The basic command is as follows.

Script-Migration
dotnet ef migrations script

這個命令有多個選項。There are several options to this command.

執行指令碼之前,from 移轉應該是套用到資料庫的最後一個移轉。The from migration should be the last migration applied to the database before running the script. 若未套用任何移轉,請指定 0 (此為預設)。If no migrations have been applied, specify 0 (this is the default).

執行指令碼之後,to 移轉是套用到資料庫的最後一個移轉。The to migration is the last migration that will be applied to the database after running the script. 預設為您專案中的最後一個移轉。This defaults to the last migration in your project.

您可以選擇產生等冪指令碼。An idempotent script can optionally be generated. 當移轉尚未套用到資料庫時,此指令碼才適用於移轉。This script only applies migrations if they haven't already been applied to the database. 當您不確定套用到資料庫的上一個移轉是哪項,或是要部署到可能在不同移轉的多個資料庫時,這個方法很實用。This is useful if you don't exactly know what the last migration applied to the database was or if you are deploying to multiple databases that may each be at a different migration.

在執行階段套用移轉Apply migrations at runtime

某些應用程式在啟動或初次執行期間,可能會想要在執行階段套用移轉。Some apps may want to apply migrations at runtime during startup or first run. 請使用 Migrate() 方法來執行此動作。Do this using the Migrate() method.

此方法的基礎建立在 IMigrator 服務之上,其可用於更進階的案例。This method builds on top of the IMigrator service, which can be used for more advanced scenarios. 您可以使用 DbContext.GetService<IMigrator>() 來加以存取。Use DbContext.GetService<IMigrator>() to access it.

myDbContext.Database.Migrate();

警告

  • 並非所有應用程式都適合此方法。This approach isn't for everyone. 雖然這相當適合具本機資料庫的應用程式,但大多數應用程式會需要更強固的部署策略,例如產生 SQL 指令碼。While it's great for apps with a local database, most applications will require more robust deployment strategy like generating SQL scripts.
  • 請勿在 Migrate() 之前呼叫 EnsureCreated()Don't call EnsureCreated() before Migrate(). EnsureCreated() 會略過移轉而建立結構描述,因此造成 Migrate() 失敗。EnsureCreated() bypasses Migrations to create the schema, which causes Migrate() to fail.

後續步驟Next steps

如需詳細資訊,請參閱Entity Framework Core 工具參考 - EF CoreFor more information, see Entity Framework Core 工具參考 - EF Core.