管理移轉

當您的模型變更時,移轉會在一般開發過程中新增和移除,而且移轉檔案會簽入您專案的原始檔控制中。 若要管理移轉,您必須先安裝 EF Core 命令列工具

秘訣

如果 DbContext 與啟始專案位於不同的組件中,您可以在套件管理員主控台工具.NET Core CLI 工具中明確指定目標和啟始專案。

新增移轉

變更模型之後,您可以新增該變更的移轉:

dotnet ef migrations add AddBlogCreatedTimestamp

您能夠以類似版本控制系統中認可訊息的方式來使用移轉名稱。 例如,如果變更是您實體上的 BlogCreatedTimestamp 屬性,您可能會選擇類似AddBlogCreatedTimestamp的名稱。

會新增三個檔案到您移轉目錄下的專案:

  • XXXXXXXXXXXXXX_AddCreatedTimestamp.cs--主要移轉檔案。 包含套用移轉 (在 Up 中) 及予以反轉 (在 Down 中) 的必要作業。
  • XXXXXXXXXXXXXX_AddCreatedTimestamp.Designer.cs--移轉中繼資料檔案。 包含 EF 使用的資訊。
  • MyContextModelSnapshot.cs - 您目前模型的快照集。 用來決定新增下一個移轉時所要變更的項目。

檔案名稱中的時間戳記有助於使其依時間先後順序排列,以便您查看變更的進展。

命名空間

您可以自由地手動移動移轉檔案及變更其命名空間。 新的移轉會作為最後一個移轉的同層級建立。 或者,您也可以在產生時間指定目錄,如下所示:

dotnet ef migrations add InitialCreate --output-dir Your/Directory

注意

在 EF Core 5.0 中,您也可以使用 --namespace 來變更與目錄無關的命名空間。

自訂移轉程式碼

雖然 EF Core 通常會建立精確的移轉,但您應該一律檢閱程式碼,並確定它對應至所需的變更;在某些情況下,甚至需要這麼做。

資料行重新命名

需要自訂移轉的一個值得注意的範例是重新命名屬性時。 例如,如果您將 屬性重新 Name 命名為 FullName ,EF Core 將會產生下列移轉:

migrationBuilder.DropColumn(
    name: "Name",
    table: "Customers");

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

EF Core 通常無法知道何時要卸載資料行,並建立新的資料行, (兩個不同的變更) ,以及何時應該重新命名資料行。 如果依原樣套用上述移轉,所有客戶名稱都會遺失。 若要重新命名資料行,請使用下列專案取代上述產生的移轉:

migrationBuilder.RenameColumn(
    name: "Name",
    table: "Customers",
    newName: "FullName");

秘訣

當作業可能導致資料遺失時 (例如卸除資料行),移轉建立程序會引發警告。 如果您看到該警告,請務必檢閱移轉程式碼的正確性。

新增原始 SQL

雖然可以透過內建 API 來重新命名資料行,但在許多情況下無法達成。 例如,我們可能會想要以單一的新 FullName 屬性取代現有的 FirstNameLastName 屬性。 EF Core 所產生的移轉如下:

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

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

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

如同先前一樣,這會導致不必要的資料遺失。 為了從舊資料行傳輸資料,我們會重新排列移轉,並導入原始 SQL 作業,如下所示:

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

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

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

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

透過原始 SQL 進行任意變更

未經處理的 SQL 也可以用來管理 EF Core 不知道的資料庫物件。 若要這樣做,請新增移轉而不進行任何模型變更;會產生空的移轉,然後您可以填入原始 SQL 作業。

例如,下列移轉會建立SQL Server預存程式:

migrationBuilder.Sql(
@"
    EXEC ('CREATE PROCEDURE getFullName
        @LastName nvarchar(50),
        @FirstName nvarchar(50)
    AS
        RETURN @LastName + @FirstName;')");

秘訣

EXEC 當語句必須是 SQL 批次中的第一個或只有一個時,就會使用 。 它也可以用來解決等冪移轉腳本中的剖析器錯誤,這些腳本在資料表上目前不存在參考的資料行時可能發生。

這可以用來管理資料庫的任何層面,包括:

  • 預存程序
  • 全文檢索搜尋
  • 函式
  • 觸發程序
  • 檢視

在大部分情況下,EF Core 會在套用移轉時,自動將每個移轉包裝在自己的交易中。 不幸的是,某些移轉作業無法在某些資料庫中的交易內執行;在這些情況下,您可以透過傳遞 suppressTransaction: truemigrationBuilder.Sql 來退出宣告交易。

移除移轉

在您新增移轉時,有時候會發現您必須在套用 EF Core 模型之前對其進行其他變更。 若要移除上一個移轉,請使用此命令。

dotnet ef migrations remove

移除移轉後,您可以進行其他模型變更並再次予以新增。

警告

請避免移除已套用至生產資料庫的任何移轉。 這樣做表示您無法從資料庫還原這些移轉,而且可能會中斷後續移轉所做的假設。

列出移轉

您可以列出所有現有的移轉,如下所示:

dotnet ef migrations list

重設所有移轉

在某些情況下,可能需要移除所有移轉並開始。 藉由刪除您的 Migrations 資料夾並卸載資料庫,即可輕鬆完成此作業;此時,您可以建立新的初始移轉,其中包含整個目前的架構。

您也可以重設所有移轉,並建立單一移轉,而不會遺失您的資料。 這有時稱為「四分割」,並牽涉到一些手動工作:

  • 刪除您的 移轉 資料夾
  • 建立新的移轉,並為其產生 SQL 腳本
  • 在您的資料庫中,從移轉歷程記錄資料表中刪除所有資料列
  • 將單一資料列插入移轉歷程記錄,以記錄已套用第一個移轉,因為您的資料表已經存在。 插入 SQL 是上述 SQL 腳本中產生的最後一個作業。

警告

刪除Migrations資料夾時,任何自訂移轉程式碼都會遺失。 任何自訂專案都必須手動套用至新的初始移轉,才能保留。

其他資源