使用現有資料庫Code First 移轉
注意
僅限 EF4.3 及更新版本 - 在 Entity Framework 4.1 中導入了此頁面所討論的功能、API 等。 如果您使用的是較早版本,則不適用部分或全部的資訊。
本文涵蓋將Code First 移轉與現有資料庫搭配使用,而該資料庫不是由 Entity Framework 所建立的資料庫。
注意
本文假設您知道如何在基本案例中使用Code First 移轉。 如果您未這麼做,則必須先閱讀 Code First 移轉 再繼續。
步驟 1:建立模型
您的第一個步驟是建立以現有資料庫為目標的程式碼優先模型。 「 程式碼優先至現有資料庫 」主題提供如何執行這項操作的詳細指引。
注意
請務必先遵循本主題的其餘步驟,再對需要變更資料庫架構的模型進行任何變更。 下列步驟需要模型與資料庫架構同步。
步驟 2:啟用移轉
下一個步驟是啟用移轉。 您可以在 封裝管理員 主控台中執行 Enable-Migrations 命令來執行這項操作。
此命令會在名為 Migrations 的解決方案中建立資料夾,並將單一類別放在其內稱為 Configuration。 Configuration 類別是您為應用程式設定移轉的位置,您可以在Code First 移轉 主題中 深入瞭解。
步驟 3:新增初始移轉
一旦建立並套用至本機資料庫,您可能也想要將這些變更套用至其他資料庫。 例如,您的本機資料庫可能是測試資料庫,您最終可能會想要將變更套用至實際執行資料庫,以及/或其他開發人員測試資料庫。 此步驟有兩個選項,您應該挑選的選項取決於任何其他資料庫的架構是否空白,或目前符合本機資料庫的架構。
- 選項一:使用現有的架構作為起點。 當您未來將套用移轉的其他資料庫與本機資料庫相同的架構時,您應該使用此方法。 例如,如果您的本機測試資料庫目前符合生產資料庫的 v1,而您稍後會套用這些移轉,將生產資料庫更新至 v2,您可能會使用此方法。
- 選項二:使用空白資料庫作為起點。 當未來將套用移轉的其他資料庫是空的(或尚不存在)時,您應該使用此方法。 例如,如果您使用測試資料庫開始開發應用程式,但未使用移轉,您稍後會想要從頭開始建立生產資料庫,您可能會使用這個方法。
選項一:使用現有的架構作為起點
Code First 移轉會使用儲存在最近移轉中的模型快照集來偵測模型的變更(您可以在 Team Environment 的Code First 移轉中找到詳細資訊 )。 由於我們將假設資料庫已經有目前模型的架構,因此會產生空的 (no-op) 移轉,此移轉會將目前的模型作為快照集。
- 在 封裝管理員 主控台中執行 Add-Migration InitialCreate –IgnoreChanges 命令。 這會建立空移轉,並將目前的模型作為快照集。
- 在 封裝管理員 主控台中執行 Update-Database 命令。 這會將 InitialCreate 移轉套用至資料庫。 由於實際的移轉不包含任何變更,因此只會將資料列新增至__MigrationsHistory資料表,指出此移轉已套用。
選項二:使用空白資料庫作為起點
在此案例中,我們需要移轉能夠從頭開始建立整個資料庫,包括已存在於本機資料庫中的資料表。 我們將產生 InitialCreate 移轉,其中包含建立現有架構的邏輯。 然後,我們會讓現有的資料庫看起來像已套用此移轉。
- 在主控台 封裝管理員中執行 Add-Migration InitialCreate 命令。 這會建立移轉以建立現有的架構。
- 批註化新建立移轉之 Up 方法中的所有程式碼。 這可讓我們「套用」移轉至本機資料庫,而不需要嘗試重新建立已經存在的所有資料表等等。
- 在 封裝管理員 主控台中執行 Update-Database 命令。 這會將 InitialCreate 移轉套用至資料庫。 由於實際的移轉不包含任何變更(因為我們暫時將其批註化),因此只會將資料列新增至__MigrationsHistory資料表,指出此移轉已套用。
- 取消批註 Up 方法中的程式碼。 這表示當此移轉套用至未來的資料庫時,本機資料庫中已存在的架構將會由移轉建立。
要注意的事項
針對現有的資料庫使用移轉時,您需要注意一些事項。
預設/匯出名稱可能不符合現有的架構
當移轉建構移轉時,會明確指定資料行和資料表的名稱。 不過,還有其他資料庫物件,移轉會在套用移轉時計算的預設名稱。 這包括索引和外鍵條件約束。 以現有的架構為目標時,這些匯出名稱可能不符合您資料庫中實際存在的名稱。
以下是一些需要注意下列情況的範例:
如果您使用步驟 3 的「選項一:使用現有的架構作為起點」:
- 如果模型中的未來變更需要變更或卸載以不同方式命名的其中一個資料庫物件,您必須修改 Scaffolded 移轉,以指定正確的名稱。 移轉 API 有選擇性的 Name 參數,可讓您執行這項操作。 例如,您現有的架構可能有具有 BlogId 外鍵資料行的 Post 資料表,其索引名為 IndexFk_BlogId。 不過,根據預設,移轉會預期此索引會命名為 IX_BlogId。 如果您變更導致卸載此索引的模型,則必須修改 Scaffolded DropIndex 呼叫來指定IndexFk_BlogId名稱。
如果您使用步驟 3 中的「選項二:使用空白資料庫作為起點」:
- 嘗試對本機資料庫執行初始移轉的 Down 方法(也就是還原為空白資料庫),可能會失敗,因為移轉會嘗試使用不正確的名稱卸載索引和外鍵條件約束。 這只會影響本機資料庫,因為會使用初始移轉的 Up 方法從頭開始建立其他資料庫。 如果您想要將現有的本機資料庫降級為空狀態,最簡單的方式就是卸載資料庫或卸載所有資料表。 在此初始降級之後,所有資料庫物件都會以預設名稱重新建立,因此此問題不會再次出現。
- 如果模型中的未來變更需要變更或卸載其中一個以不同方式命名的資料庫物件,則這不適用於您現有的本機資料庫,因為名稱不符合預設值。 不過,它會針對「從頭開始」建立的資料庫運作,因為它們會使用移轉選擇的預設名稱。 您可以在本機現有資料庫上手動進行這些變更,或考慮讓移轉從頭重新建立您的資料庫,就像在其他電腦上一樣。
- 使用初始移轉的 Up 方法建立的資料庫可能會與本機資料庫稍有不同,因為會使用索引和外鍵條件約束的匯出預設名稱。 您最終可能也會有額外的索引,因為移轉預設會在外鍵資料行上建立索引 , 這可能是原始本機資料庫中的情況。
並非所有資料庫物件都會在模型中表示
移轉不會處理不屬於模型的資料庫物件。 這包括檢視、預存程式、許可權、不屬於模型一部分的資料表、其他索引等等。
以下是一些需要注意下列情況的範例:
- 無論您在「步驟 3」中選擇的選項為何,如果模型中的未來變更需要變更或卸載這些額外的物件移轉,則移轉將不知道進行這些變更。 例如,如果您卸載具有其他索引的資料行,則移轉將不知道卸載索引。 您必須手動將此新增至 Scaffold 的移轉。
- 如果您使用「選項二:使用空白資料庫作為起點」,則初始移轉的 Up 方法將不會建立這些額外的物件。 您可以視需要修改 Up 和 Down 方法,以處理這些額外的物件。 針對移轉 API 中原生不支援的物件,例如檢視表,您可以使用 Sql 方法來執行原始 SQL 來建立/卸載它們。