在本節中,您將使用實體框架代碼先行遷移功能對模型類進行修改,並使修改應用到數據庫中。
默認情況下,當您使用實體框架代碼先行自動創建一個數據庫,像你在本教程前面做的那樣,代碼首先添加一張表到數據庫中,以幫助跟蹤數據庫架構是否是同步的模型類是產生的。如果它們不同步,實體框架拋出一個錯誤。這使得它更容易在早期開發時跟蹤發現問題,否則,你可能在運行時發現隱晦錯誤。
為模型修改建立代碼先行遷移
如果您使用的是Visual Studio 2012,在“解決方案資源管理器”中雙擊Movies.mdf的文件,打開數據庫工具。Visual Studio Express for Web將顯示“數據庫資源管理器,Visual Studio2012將顯示”服務器資源管理器“。如果您使用的是Visual Studio 2010中,使用SQL Server對象資源管理器。
在數據庫工具中,在MovieDbContext上右鍵點擊並選擇刪除。
回到解決方案資源管理器。在 Movies.mdf file文件上右鍵單擊並選擇刪除。
譯者注:此處看上去很費解,事實上,第一步實際執行的操作是刪除數據庫鏈接,彈出的刪除確認提示也說明了這一點,第二步則是在解決方案管理器里真正刪除數據庫文件。
生成應用程序,確認沒有編譯錯誤。
在vs2012工具菜單里,點擊“庫程序包管理器”-》程序包管理器控制台
在控制台的PM>標記后,輸入“Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDbContext”
輸出如下信息:
PM> Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDbContext
正在檢查上下文的目標是否為現有數據庫...
已為項目 MvcMovie 啟用 Code First 遷移。
PM>
上面的Enable-Migrations命令創建了一個新的Migrations文件夾,並在該目錄下創建了Configuration.cs文件。
使用Visual Studio打開Configuration.cs文件。使用以下代碼替換Seed方法內容:
protected override void Seed(MvcMovie.Models.MovieDbContext context) { context.Movies.AddOrUpdate( m => m.Name, new Movie { Name = "少年派的奇幻漂流之旅",Date=DateTime.Now }, new Movie { Name = "一九四二", Date = DateTime.Now }, new Movie { Name = "王的盛宴", Date = DateTime.Now } ); }
以上代碼需要類中導入名稱空間using MvcMovie.Models;
代碼先行遷移機制在每次遷移后調用Seed方法,如果存在行數據,則該方法更新現有數據,如果不存在,則該方法插入數據。
按下CTRL+SHIFT+B來生成項目(如果此處不執行此生成操作,后續的步驟會失敗)
下一步是創建DbMigration 類來初始化遷移。遷移將創建一個新的數據庫,這也是在前面步驟中刪除數據庫文件的原因。
在程序包管理器控制台窗口,輸入命令"add-migration Initial"來創建初始遷移。其中Initial可以是任意名稱,用來標識創建的初始文件。控制台輸出如下:
PM> add-migration Initial
正在為遷移“Initial”搭建基架。
此遷移文件的設計器代碼包含當前 Code First 模型的快照。在下一次搭建遷移基架時,將使用此快照計算對模型的更改。如果對要包含在此遷移中的模型進行其他更改,則您可通過再次運行“Add-Migration 201212060747227_Initial”重新搭建基架。
PM>
代碼先行遷移機制在Migrations文件夾下創建另外一個類文件,文件名為時間戳+下划線+ Initial.cs,例如201212060747227_Initial.cs,該類包含了創建數據庫架構的代碼。遷移文件名預置為時間戳有助於排序。查看該文件,包含了創建Movie庫表的說明。當你更新數據庫時,該類將被執行,創建數據庫架構。隨后,Seed方法將被執行,測試數據被添加其中。
在程序包管理器控制台窗口,鍵入"update-database"命令來創建數據庫和執行Seed方法。
PM> update-database
指定“-Verbose”標記以查看應用於目標數據庫的 SQL 語句。
正在應用基於代碼的遷移: [201212060747227_Initial]。
正在應用基於代碼的遷移: 201212060747227_Initial。
正在運行 Seed 方法。
PM>
如果遇到表已存在的錯誤而不能創建,很可能是你刪除數據庫后,執行update-database前運行了應用程序(重新編譯程序,自動創建了數據庫)。這種情況下,再次刪除數據庫文件,並執行 update-database命令。如果仍然出錯,刪除migrations目錄和內容,重新開始本教程操作。
運行應用程序,導航到 /Movies 地址。種子數據顯示出來了。
譯者注:此處的種子數據,實際上指的是一些庫表創建后添加的一些測試數據或者系統初始化數據,如系統參數,部門的根目錄等。
為Movie模型增加評價屬性
為已存在的影片類增加評價屬性。打開 Models\Movie.cs文件,增加Rating屬性如下
public string Rating { get; set; }
通過生成菜單或者CTRL+SHIFT+B快捷鍵編譯應用程序。
現在你已經更新了模型類,同樣需要更新 \Views\Movies\Index.cshtml 和\Views\Movies\Create.cshtml 視圖模板。
打開\Views\Movies\Index.cshtml 文件,在Price列后增加列標題<th>Rating</th>。然后在模板結尾附近增加<td> 列標簽。
Create視圖中也做相應修改,此處不再詳細描述。
現在你已經更新了程序代碼來支持新增的評價屬性。運行程序並導航到 /Movies ,你會發現以下錯誤:
支持“MovieDbContext”上下文的模型已在數據庫創建后發生更改。請考慮使用 Code First 遷移更新數據庫(http://go.microsoft.com/fwlink/?LinkId=238269)。
發生該錯誤的原因是你在程序中更新了Movie模型類,與已存在的數據庫中的Movie庫表結構不同(數據庫Movie表中沒有Rating列)。
解決此問題,有以下幾種方法:
1. 令 Entity Framework依據新模型類架構自動刪除和重新常見數據庫。該方法非常適用於開發在測試數據上進行動態開發;可以使你快速演化模型和數據庫表結構。不過,其缺點是,會丟失當前數據庫中已存在的數據—因此你不想在生產數據庫上使用這種方法。在測試數據庫上采用初始化器來自動產生數據庫通常是一種高效開發應用程序的方式。想查看更多關於Entity Framework初始化器方面的信息,請參閱Tom Dykstra寫的 ASP.NET MVC/Entity Framework tutorial.
2. 顯式地修改現有的數據庫架構,以便它匹配模型類。這種方法的優點是保留了現存數據。你可以通過手動或者創建一個數據庫腳本來做變更。
3. 使用代碼先行遷移來更新數據庫架構
在這個課程中,我們將使用上面所說的第三種方式,即代碼先行遷移
更新Seed方法,使其為新增的列提供值。打開Migrations\Configuration.cs文件,為每個Movie對象增加Rating值。
生成解決方案,然后打開庫管理器控制台窗口,輸入以下命令add-migration AddRatingMig
add-migration 命令告訴遷移框架對比當前模型和庫表結果差異,生成必要的代碼來使庫表跟模型適配。AddRatingMig名字可以是任意的,只是遷移文件的標識符。采用有意義的名字有助於遷移操作。
當命令執行完畢后,Visual Studio打開類文件,創建了新的DbMIgration 類,在其Up方法里,你可以看到創建新列的代碼。
public partial class AddRatingMig : DbMigration { public override void Up() { AddColumn("dbo.Movies", "Rating", c => c.String()); } public override void Down() { DropColumn("dbo.Movies", "Rating"); } }
生成解決方案,庫管理器控制台窗口輸入"update-database"命令。
PM> update-database
指定“-Verbose”標記以查看應用於目標數據庫的 SQL 語句。
正在應用基於代碼的遷移: [201212060835020_AddRatingMig]。
正在應用基於代碼的遷移: 201212060835020_AddRatingMig。
正在運行 Seed 方法。
PM>
運行應用程序,導航到/Movies,你將看到新增的Rating列
同樣,你需要修改Edit和Delete視圖,增加Rating屬性。
你可以再次在庫管理器控制台里輸入"update-database”命令,發現沒有修改被應用,因為當前數據庫表結構跟模型匹配。
在本節中,你學習了如何修改模型對象,並保持與數據庫同步。同時學習了如何創建帶有示例數據的數據庫的方法。下面我們將學習如何為模型類添加驗證邏輯使業務規則生效。
譯者注:本文說的比較零散,在此做下總結,要使用代碼先行提供的遷移功能來保證模型和數據庫自動匹配,需要在庫程序包管理器里依次執行以下命令:
1.啟用遷移功能:Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDbContext
2.建立初態:add-migration Initial
3.自動比對差異生成遷移類:add-migration AddRatingMig
4.將遷移應用到數據庫:update-database
在實際的項目開發過程或者維護過程中,因為業務需求或者設計的變動,經常需要對庫表增刪字段,在項目團隊多人合作方式開發情況下,很容易遺漏對數據庫的修改,而遷移功能就很好地保證了這一點,“自動”記錄了模型變動需要對庫表進行的變更操作。
本教程所有文章導航
本系列共10篇文章,翻譯自Asp.Net MVC4 官方教程,由於本系列文章言簡意賅,篇幅適中,從一個示例開始講解,全文最終完成了一個管理影片的小系統,非常適合新手入門Asp.Net MVC4,並由此開始開發工作。
原文供9篇文章,譯者將其中第6篇拆成了2篇
1. Asp.Net MVC4 入門介紹
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/03/2800210.html
2. 添加一個控制器
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-controller
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/04/2801949.html
3. 添加一個視圖
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-view
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/04/2801988.html
4. 添加一個模型
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-model
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2803012.html
5. 從控制器訪問數據模型
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2803429.html
6.查看Edit方法和Edit視圖
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2804100.html
http://www.cnblogs.com/seawaving/archive/2012/12/06/2804590.html
7. 為Movie模型和庫表添加字段
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/06/2805401.html
8. 為模型添加驗證
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/06/2806322.html
9. 查看Detail和Delete方法
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/10/2811064.html