2016 年 1 月

第 31 卷,第 1 期

本文章是由機器翻譯。

資料點 EF7 移轉: 非全新,但功能絕對經改良

Julie Lerman |2016 年 1 月

Julie Lerman有了 Entity Framework 7,Code First 移轉經歷了巨大的轉變。基本概念和移轉步驟維持不變,工作流程已變成多清理和更多易懂,而現在可以開始運作得很好與原始檔控制。

EF7 帶來兩種移轉: 熟悉各種您使用 NuGet 和大部分的.NET 專案,以及您 DNX 執行階段的一部分執行的 ASP.NET 5 應用程式類型。

我還介紹這些其中一種 Pluralsight 課程 (bit.ly/1MThS4J)。雖然我在該課程中使用 beta 4 版本與發行候選版本 1 (RC1) 現在使用之間變更幾件事,該課程仍看見作用中的移轉,或了解的一些差異的絕佳資源。

但隨著 RC1,就會被視為功能即將推出 rtm,另一個查看關閉 EF7 移轉的時間。我將開始熟悉的 Windows PowerShell 命令,在封裝管理員主控台的 Visual Studio。然後,當您想要使用 ASP.NET 5 和 DNX,我將討論這些命令。本文假設您有一些現有的 EF6 或更早版本中的資料庫初始設定和移轉功能。

無其他 Magic 資料庫初始化,使用 「 移轉 」

支援魔法昂貴,限制,以及建立很多麻煩。並在 DbInitializers,它會建立許多混淆。因此 EF DbInitializers 以及 CreateDatabaseIfNotExists 的預設行為會立即消失。取而代之的是可讓您明確建立和刪除資料庫 (EnsureDeleted、 EnsureCreated),我會很高興在整合測試中使用的邏輯。

EF7 被設計來使用 「 移轉 」。現在,它們應該是預設的工作流程。

因為移轉已附加到 EF 以及使用它們所需的建置基礎結構的位元,就已存在 」 啟用移轉 」 命令。命令未安裝任何新的 Api。它只會加入專案資料夾和新 DbMigrationConfiguration 類別至專案。EF7,與相關的邏輯是內部,因此您不需要明確地告訴 EF 您想要使用 「 移轉 」。

請記住,EF7 是可組合。並非所有人會想要或需要移轉,因此如果您這樣做,您需要安裝的套件選擇的移轉命令,其中包含它們:

install-package entityframework.commands -pre

EF7 移轉命令

使用 Windows PowerShell Get-help 指令程式會顯示目前 (RC1) 的移轉命令,如所示 [圖 1。這份清單應該是相同的 RTM。

移轉命令,如下所列透過 NuGet 封裝管理員 Get 命令
圖 1] 的移轉命令列出透過 NuGet 封裝管理員 Get 命令

也請注意,更新資料庫不再有"-指令碼 」 參數。就會只什麼其名所示: 更新資料庫。一如往常,不建議在實際資料庫上使用這個命令。[圖 2 顯示 Update Database 命令的詳細資料。

更新資料庫的語法和參數
[圖 2 更新資料庫的語法和參數

若要建立指令碼,您可以使用新的指令碼移轉命令。且不再秘密的配方,讓建立具有等冪性指令碼 (EF6 引入)。等冪的方式為參數,您所見的 [圖 3

指令碼移轉參數
[圖 3 指令碼移轉參數

針對移轉歷程記錄模型的快照集的重大變更

已從 EF7 移除自動移轉。由於,管理移轉較簡單,而且現在支援原始檔控制。

為了要判斷如何進行移轉,先前移轉的歷程記錄已存在。每次執行 add-migration 命令中,API 會查看該歷程記錄資訊。之前,移轉會儲存編碼的版本之模型的每個移轉快照集 (最近) 名為 _MigrationHistory 資料表中的資料庫中。這是 EF 已用來找出需要完成的移轉。每次新增移轉已執行,只代表來回存取資料庫讀取此記錄,且是很多問題的來源。

使用 EF7,除了在移轉資料夾中,熟悉移轉檔案 (透過加入移轉),建立移轉作業時 EF7 也會建立檔案來儲存目前的模型快照集。說明使用 Fluent API 語法,用於設定模型。如果您對模型進行變更,然後再新增移轉,快照集取得修訂目前完整模型的描述。[圖 4 顯示移轉檔案,將會介紹新的字串,稱為"MyProperty"。

[圖 4 完成 newStringInSamurai 移轉類別

public partial class newStringInSamurai : Migration
  {
    protected override void Up(MigrationBuilder migrationBuilder)
    {
      migrationBuilder.AddColumn<string>(
        name: "MyProperty",
        table: "Samurai",
        nullable: true);
    }
    protected override void Down(MigrationBuilder migrationBuilder)
    {
      migrationBuilder.DropColumn(name: "MyProperty", table: "Samurai");
    }
  }

而這裡是更新 ModelSnapshot 類別,讓您查看"MyProperty"現在是 Samurai 類別描述的一部分的部分:

modelBuilder.Entity("EF7Samurai.Domain.Samurai", b =>
  {
    b.Property<int>("Id")
      .ValueGeneratedOnAdd();
    b.Property<string>("MyProperty");
    b.Property<string>("Name");
    b.HasKey("Id");
  });

因此,個別的移轉說明變更內容,如往常般。但是現在,在專案中,您永遠都具有完整的模型。這表示當您新增新的移轉,EF 沒有前往找出先前模型看起來像是資料庫。所需的是正確的。更重要的是,這很好的原始檔控制因為它會直接出現在程式碼中,可以 diffed 而且就像任何其他檔案一樣的原始檔控制來合併。它不是藏可能甚至無法存取您的小組成員的資料庫中。EF7 之前, 發生不適合用來管理原始檔控制中的移轉。您稍早的版本進行移轉的相關指引該 EF7 中找到 「 程式碼第一次移轉在小組環境 」 (bit.ly/1OVO3qr)。這篇文章一開始的建議: 「 喝杯咖啡,您需要閱讀本文。 」

與 EF7,在資料庫中的移轉歷程記錄資料表 ([圖 5) 現在會儲存只移轉作業的識別碼和建立它的 EF 的版本。同樣地,這是儲存快照集本身插入此資料表中的舊版本中的大量變更。更新資料庫將會檢查此資料表來查看已套用的移轉,並套用任何遺失,即使不是連續的。這項作業需要動到資料庫,因為我會看到沒有問題的快速前檢查針對此案例中的資料庫移轉。

Dbo_EFMigrationsHistory 顯示移轉加入資料表
[圖 5 dbo_EFMigrationsHistory 顯示移轉加入資料表

您不再需要該廢話有關無法新增移轉,如果先前尚未套用到資料庫尚未處理。副作用的自動移轉,導致許多人再度到紊亂的混淆。現在您可以建置移轉您的方案中視需要然後當您準備好更新資料庫。

因為 EF7 會儲存在專案模式快照集,您不應該只移轉檔案從專案刪除因為快照集將會是不正確。因此,以及變更移轉至工作流程是新的命令: 移除移轉。移除移轉被設計來復原最有可能您剛才加入並改變了主意然後有關套用至資料庫之前的移轉。此命令會在您的專案中的兩件事: 它會移除最新的移轉檔案和它,然後更新快照集資料夾中的檔案移轉。有趣的是,這不會重建以模型為基礎的快照集。相反地,它會修改根據中取出 Designer.cs 檔案以及每個快照集所建立的模型快照集的快照集。我在測試這個外,所見,如果我沒有變更模型 (亦即,未移除不必要的屬性 Samurai 類別),快照集仍然已修正根據移轉。但別忘了太修正您的模型。否則模型和快照集同步,最有可能,您的資料庫結構描述也會與模型不同步。

附帶一提,Brice Lambson,EF 小組成員負責移轉,共用聽我說,如果您以手動方式刪除移轉檔案,移除移轉非常下次呼叫將發現並修正不會刪除另一個移轉檔案快照集。

像加入移轉移除移轉不會影響資料庫。不過,它不會檢查以查看是否已套用移轉資料庫的移轉歷程記錄檔中。如果是,您無法使用移除移轉至少還沒有。

聽起來很令人困惑,我知道。不過我仍想移除移轉,因為替代方法是只保留向前移動,並加入移轉,每當您改變心意。困惑給其他小組成員或未來您。此外,它是參與原始檔控制者方便而讓移轉付點代價。

若要協助釐清, [圖 6 具有回溯不想要的移轉的指引。圖表假設 「 Migration1 」 已套用至資料庫和 「 Migration2 」 已建立,但永遠不會套用至資料庫。

[圖 6 處理的不必要的移轉

資料庫狀態 命令 執行命令的工作
更新資料庫 Migration2 後執行 移除移轉

1.確認 Migration2 不是記錄資料表

2.刪除 Migration2.cs

3.修正 Snapshot.cs 以反映前一次移轉

更新資料庫 Migration2 後執行

更新資料庫 Migration1

移除移轉

1.執行 SQL 的 「 卸除 」 Migration2 方法

2.從歷程記錄資料表移除 Migration2 資料列

1.刪除 Migration2.cs

2.修正 Snapshot.cs 以反映前一次移轉

如果您需要復原多項移轉,啟動藉由呼叫後面的最後一個很好的移轉名稱更新資料庫。然後您可以呼叫 remove 移轉回復移轉和快照集,一次。

有了這項重點,「 移轉 」,別忘了這些移轉會反映模型的變更。這就是一個最後提醒,您必須手動復原模型的變更,然後移除反映這些變更的任何移轉。

反向工程與 Scaffold DbContext

舊版的 EF 提供反向工程資料庫到 Code First 模型的能力。Microsoft 提供這項功能,可透過 Entity Framework 的強大工具,從 EF6、 透過 EF 設計工具。另外還有協力廠商工具,例如受歡迎 (免費) 延伸模組,EntityFramework 反轉 POCO 產生器 (reversepoco.com)。因為 EF7 沒有設計工具,scaffold 命令被為了執行這項作業。

以下是 Scaffold DbContext 的參數:

Scaffold-DbContext [-Connection] <String> [-Provider] <String>
                   [-OutputDirectory <String>] [-ContextClassName <String>]
                   [-Tables <String>] [-DataAnnotations] [-Project <String>]
                   [<CommonParameters>]

我很熱衷於 fluent API 的組態,讓我很高興,同樣地,這些都是預設值,您需要選擇加入 DataAnnotations 旗標改為使用資料註解。以下是進行反向工程,從現有資料庫使用該參數的命令 (我也可以選取的資料表建立的結構,但我不用這裡):

Scaffold-DbContext
   -Connection "Server = (localdb)\mssqllocaldb; Database=EF7Samurai;"
   -Provider entityframework.sqlserver
   -OutputDirectory "testRE"

做為 [圖 7 所示,這會產生新的資料夾和數個檔案加入至我的專案。我有很多檢查這些類別,因為這是一項重要功能,但我就把這供日後使用。

Scaffold DbContext 的結果
[圖 7 的 Scaffold DbContext 的結果

移轉命令的 DNX 版本

您在 [封裝管理員主控台中執行的命令是 Windows PowerShell 命令,且 Windows PowerShell,當然,Windows 的一部分。其中最重要功能的 ASP.NET 5 — 和 EF7 — 就是它們不再是取決於 Windows。DNX 是一個輕量型的.NET 執行環境,可以在 OS X 和 Linux,以及 Windows 上執行。您可以進一步資訊,請參閱 bit.ly/1Gu34wX。Entityframework.commands 封裝包含 DNX 環境,以及移轉命令。以下是這些命令,以快速瀏覽。

如果您要使用 Visual Studio 2015,這是我將在此示範,可以直接在封裝管理員主控台中執行命令。否則,您執行它們在相關的作業系統的命令列中。查看 Nate McMaster 第 9 頻道視訊在他代碼 EF7 和 mac 上的移轉(bit.ly/1OSUCdo)

首先,您必須確定您是在正確的資料夾 — 這是您的模型所在專案的資料夾。預設專案] 下拉式清單中不被與您的檔案路徑。使用正確的資料夾 dir 命令,以查看您所在,然後只是 cd。Tab 鍵自動完成是您的朋友。在 [圖 8 您可以看到雖然預設專案 src\EF7WebAPI,才能執行 dnx 命令列在該目錄中,我必須明確將目錄變更為此專案包含我 EF7 模型的路徑。

先執行 DNX 命令取得正確的目錄
[圖 8 執行 DNX 命令之前先取得正確的目錄

一次,我可以執行命令。每一個命令,對了,需要前面 dnx,加上,而且您可以使用 dnx ef 來列出所有可用的命令。請注意該 ef 是我在 project.json 中設定的捷徑。查看我的 Pluralsight 視訊 」 經過預先 Entity framework 7"(bit.ly/PS_EF7Alpha),以查看更多有關安裝程式。

核心命令包括資料庫、 dbcontext 移轉。移轉有下列子命令:

add     Add a new migration
list    List the migrations
remove  Remove the last migration
script  Generate a SQL script from migrations

每個命令具有您可以藉由新增-查詢的參數說明,像這樣:

dnx ef migrations add --help

例如,如果初始移轉名稱,然後命令為:

dnx migrations add initial

請記住,這些全都是稍早在本文中,所以您會發現參數,可讓您指定專案、 DbContext 和其他詳細資料的相同命令。指令碼命令已具有等冪性參數,如先前所述。但不同的 dnx 指令碼命令的一件事是,依預設,指令碼只列出在 [命令] 視窗中。您必須明確指定輸出 < 檔案 > 參數推送至檔案的指令碼。

下列命令會套用到資料庫的移轉:

dnx ef database update

Dbcontext 命令具有兩個指令: dbcontext 清單會列出所有可在專案中發現 DbContexts。以下是因為您無法取得 tab 鍵擴充功能提供在 Windows PowerShell,使用命令時,可以輕鬆地就像您一樣的選項scaffold 是 DbContext Scaffold 命令,您學到關於稍早的 dnx 版本。

整體提供更好的移轉體驗與 EF7

移除自動移轉程序,已簡化移轉 EF7 中。雖然基本概念,是相同的工作流程會更加簡潔。移除在小組環境中使用移轉的障礙非常關鍵。我喜歡這已修正原始程式碼中帶入模型快照集的方式。並允許使用 scaffold 命令的反向工程是不需依賴設計工具提供此項重要功能的好方法。

7 月 23 設計會議記錄 EF 小組 (bit.ly/1S813ro) 之後命名已勒包括所有的 Windows PowerShell 和 dnx 命令好用的資料表。我預期有最終將會更簡潔的版本中的文件,但仍找一本很有用。

我撰寫本文使用的 RC1 版本 EF7,但這個版本會被視為功能完整,因此很可能這項資訊會配合即將以及 ASP.NET 5 早期 2016 的 EF7 的版本。


Julie Lerman是 Microsoft MVP、.net 和顧問 Vermont 山區中。您可以找到她針對資料存取和使用者群組和世界各地的研討會其他.NET 主題呈現。她的部落格網址 thedatafarm.com /blog 和以及 Code First DbContext 版本中的,所有從 O'Reilly Media 是 「 程式設計 Entity Framework 」 的作者 (2009 年)。在 Twitter 上追蹤她: @julielerman 並查看她 Pluralsight 課程 juliel.me/PS 影片

感謝以下的微軟技術專家對本文的審閱: Brice Lambson