本文討論的內容是基於EF4.1版本。文中談論的現有的數據庫不是由EF建立。本文假定你已經對Code First遷移有必定的瞭解,若是不瞭解Code First遷移更新數據庫能夠查看sql
文章涉及的主題以下:數據庫
一、建立模型測試
二、可遷移性spa
三、添加一個初始遷移對象
a、使用現有的schema做爲起點索引
b、以一個空數據庫做爲起點開發
四、注意點:get
a、默認的/計算的名稱可能與現有schema不匹配同步
b、不是全部的數據庫對象都在model中表現出來it
1、建立模型
第一步是建立一個以現有數據庫爲目標的Code First model。
注意:在這個主題中,對模型作任何修改以前按照其他的步驟操做是很重要的,您的模型須要修改數據庫模式。下面的步驟須要同步模型與數據庫模式。
2、可遷移性
接下來一步是使數據遷移。你能夠在NuGet程序包管理器控制檯中運行Enable-Migrations命令來實現。
這個命令將會在你的解決方案中建立名爲Migrations的文件夾並在文件夾中建立一個名爲Configuration的類。Configuration類是用來爲應用程序配置數據遷移的。
3、添加一個初始遷移
一旦建立了數據庫遷移和應用到本地數據庫您可能還想將這些更改應用於其餘數據庫。例如,您的本地數據庫多是一個測試數據庫,你也可能最終要應用這些更改到生產數據庫或其餘開發人員測試數據庫。這一步有兩個選擇,你應該選擇取決於其餘數據庫的模式目前是不是空的或與本地數據庫的模式是否匹配。
方式一:使用現有的schema做爲起點(或做爲開始)
當其餘數據庫遷移將被應用到有相同的模式的本地數據庫時,您應該使用這種方法。例如,若是你目前本地測試數據庫匹配v1的生產數據庫以後,你將會應用這些遷移來更新生產數據庫到v2。
方式二:以一個空數據庫做爲起點(或者做爲開始)
當數據庫遷移應用到空數據庫(或者不存在的數據庫)時,你應該選擇這種方法。例如,若是你使用一個測試數據庫來開發你的應用程序,完成以後沒有使用數據庫遷移而是從頭開始建立一個生產數據庫。
4、兩種方式的具體操做
方式一:
Code First數據庫遷移經過模型的快照存儲對模型所作的最新變動。由於咱們假設數據庫已是當前模型的模式,咱們將生成一個空的(操做)以當前的模型做爲一個快照的遷移。
一、在包管理器控制檯中運行Add-Migration InitialCreate -IgnoreChanges命令。這條命令會建立一個以當前模型做爲快照的空的遷移。
二、在包管理器控制檯中運行Update-Database命令。這條命令將會把建立的初始遷移應用到數據庫。若是實際的遷移沒有包含任何的改變,那麼會簡單的添加一條記錄到__MigrationsHistory 表以代表遷移已經被應用。
方式二:
在這個方式中,咱們須要使用遷移來從頭開始建立整個數據庫——包括已經在本地數據庫存在的表。咱們將會生成一個包含這種邏輯的初始遷移並以現有的schema來建立。而後,會使遷移應用到咱們現有的數據庫中。
一、在包管理器控制檯中運行Add-Migration InitialCreate命令。這條命令會在現有的schema中建立遷移。
二、註釋掉新建立的遷移中Up方法的全部代碼。這樣作可讓咱們應用產生的遷移到本地數據庫而且EF不會去建立已經存在的全部表。
三、在包管理器控制檯中運行Update-Database命令。這會在數據庫中應用InitialCreate遷移。由於實際上遷移並不包含任何更改,那麼會簡單的添加一條記錄到__MigrationsHistory 表以代表遷移已經被應用。
四、取消Up方法中註釋掉的代碼。這就意味着當這個遷移被應用到之後的數據庫中時在本地數據庫中已經存在的schema就會經過遷移被應用。
5、注意事項
一、默認/預測的列或表的名稱與現有的數據庫的匹配
遷移爲將要遷移建立的表和列都明確地指定了名稱。然而,當使用這個遷移的時候會對數據庫中其餘的對象應用這些指定的默認的名稱。遷移中還包括索引和外鍵約束。當針對現有的schema時,這些默認的名稱與實際存在的數據庫可能不匹配。
注意如下幾點:
a、若是選擇方式一
若是未來你的model發生了改變就須要改變或者刪除其中與其餘命名不一樣的那一個數據庫對象,同時你須要修改腳手架遷移程序來指定正確的表或列名稱。Migrations APIs中有重載的方法,能夠經過修改可選的參數來實現修更名稱。例如,你的現有的數據庫可能有一個Post表,表中包含一個BlogId外鍵列,列名爲IndexFk_BlogId。然而,若是使用遷移中默認的名稱會被從新命名爲IX_BlogId。若是你修改了model將會致使刪除這個索引,你須要修改腳手架DropIndex調用來指定索引名爲IndexFk_BlogId。
b、若是選擇方式二
(1)針對你的本地數據庫嘗試執行初始遷移中的Down方法可能會失敗,由於遷移程序將會嘗試刪除名字正確的索引和外鍵。這隻會影響你的本地數據庫或表而其餘的數據庫或表將會經過初始遷移中的Up方法來從頭建立。
若是你想降級你現有的數據庫到空的狀態,經過手工實現是最簡單的方式,你能夠手動刪除數據庫或者全部的數據庫表。而後,全部的數據庫對象都會被從新建立並被命名爲默認的名稱,這樣這個問題就不會在出現。
(2)若是未來你的model發生了改變就須要改變或者刪除其中與其餘命名不一樣的那一個數據庫對象,針對你本地數據庫的程序將不能正常工做,由於數據庫對象名與默認的名稱不匹配。然而,針對從頭開始建立的數據庫的程序是能夠工做的,由於數據庫對象使用的名稱是遷移中默認的名稱。
你也能夠手動在本地數據庫中作這些修改,或者考慮使用遷移從頭來建立你的數據庫。
(3)使用初始遷移中的Up方法建立的數據庫可能與你本地數據庫有明顯的不一樣,由於以索引和外鍵約束爲默認名稱的名稱會被使用。你也能夠獲得額外的索引做爲遷移將以默認外鍵列來建立索引——建立出來的數據庫可能不是你原來的本地數據庫。
二、不是全部的數據庫對象都在model中變現出來
沒有在model中表示出來的數據庫對象不會被Migrations處理。這些沒有在model中表示出來的數據庫對象包括視圖、存儲過程、權限許可、表、索引等等。
注意如下幾點:
a、無論你選的是方式一仍是方式二,若是之後你修改了model須要修改或刪除這些額外的對象,Migrations不會知道發生了什麼樣的修改。例如,你刪除了額外對象中的一列,Migrations將不會知道你刪除的是什麼。若是想讓Migrations知道發生的修改,你須要手動將刪除的列添加到腳手架Migration中。
b、若是你選擇方式二,這些額外對象不會被初始的migration的Up方法建立。
若是你但願Up和Down方法監聽這些額外的對象,你能夠對Up和Down方法進行修改。對於對象,在Migrations API中不是一開始就被支持的,例如視圖,你可使用DbMigration.Sql方法執行SQL來建立或刪除這些對象。