一、Entity Framework Code First 簡析:
Entity Framework Code First是指,先使用Entity Framework來建立要使用Model類代碼,然后由Entity Framework來為我們自動創建數據庫和表。
創建過程中,Code First模式會檢查數據庫結構是否和Model類同步。如果不同步,Entity Framework會拋出錯誤。
【白話總結】
Code First模式指的就是——現有Model類代碼,然后Entity Framework自動生成對應的數據庫和表。
二、為Model的更改設置Code First 遷移(Setting up Code First Migrations for Model Changes)
Code First 遷移(Code First Migrations):
目的、功能: 使Model類和自動生成的數據庫、表同步。當Model代碼更改時,通過更新數據庫命令,可以生成新的和Model新類結構相一致的數據庫、表。
操作步驟:
步驟1:刪除原有數據庫連接和數據庫
從服務器資源管理器中,找到MovieDBContext,將其刪除;
在解決方案資源管理器中,找到Movies.mdf,將其刪除;
重新生成項目
步驟2: 使用程序包管理器控制台輸入命令,建立Code First Migrations
工具——庫程序包管理器——程序包管理器控制台,輸入命令:
Enable-Migrations -ContextTypeName MvcApplication1.Models.MovieDBContext
為我們的項目開啟Code First 遷移。這回同時生成一個Configuration.cs在項目的/Migrations/目錄下。
步驟3:更改Configuration.cs中Seed()方法代碼:
1 protected override void Seed(MvcApplication1.Models.MovieDBContext context) 2 { 3 // This method will be called after migrating to the latest version. 4 5 // You can use the DbSet<T>.AddOrUpdate() helper extension method 6 // to avoid creating duplicate seed data. E.g. 7 // 8 // context.People.AddOrUpdate( 9 // p => p.FullName, 10 // new Person { FullName = "Andrew Peters" }, 11 // new Person { FullName = "Brice Lambson" }, 12 // new Person { FullName = "Rowan Miller" } 13 // ); 14 // 15 context.Movies.AddOrUpdate(i => i.Title, 16 new Movie 17 { 18 Title = "When Harry Met Sally", 19 ReleaseDate = DateTime.Parse("1989-1-11"), 20 Genre = "Romantic Comedy", 21 Price = 7.99M 22 }, 23 24 new Movie 25 { 26 Title = "Ghostbusters ", 27 ReleaseDate = DateTime.Parse("1984-3-13"), 28 Genre = "Comedy", 29 Price = 8.99M 30 }, 31 32 new Movie 33 { 34 Title = "Ghostbusters 2", 35 ReleaseDate = DateTime.Parse("1986-2-23"), 36 Genre = "Comedy", 37 Price = 9.99M 38 }, 39 40 new Movie 41 { 42 Title = "Rio Bravo", 43 ReleaseDate = DateTime.Parse("1959-4-15"), 44 Genre = "Western", 45 Price = 3.99M 46 }); 47 }
這個代碼在數據庫被更新或新建后,被系統自動調用,用來初始化數據,提供測試用數據。注意導入命名空間:
usingMvcMovie.Models;
重新生成項目
步驟4:生成遷移類Initial:DbMigration
遷移類用來創建新數據庫
程序包管理器控制台中輸入命令add-migration Initial
這會在/Migrations/目錄下生成一個帶有時間戳的Initial.cs代碼,其中包含Initinal類派生自DbMigration
1 namespace MvcApplication1.Migrations 2 { 3 using System; 4 using System.Data.Entity.Migrations; 5 6 public partial class Initial : DbMigration 7 { 8 public override void Up() 9 { 10 CreateTable( 11 "dbo.Movies", 12 c => new 13 { 14 ID = c.Int(nullable: false, identity: true), 15 Title = c.String(), 16 ReleaseDate = c.DateTime(nullable: false), 17 Genre = c.String(), 18 Price = c.Decimal(nullable: false, precision: 18, scale: 2), 19 }) 20 .PrimaryKey(t => t.ID); 21 22 } 23 24 public override void Down() 25 { 26 DropTable("dbo.Movies"); 27 } 28 } 29 }
步驟5:更新數據庫
程序包管理器控制台中輸入命令update-database
這個命令會先運行步驟4中的Initial的Down和Up方法,創建新數據庫;
然后運行Seed方法添加測試數據,從而同步Model類。
三、為Movie類Model 添加一個Rating屬性
步驟1:更改/Model/Movie.cs ,添加Rating屬性:
1 public class Movie 2 { 3 public int ID { get; set; } 4 public string Title { get; set; } 5 public DateTime ReleaseDate { get; set; } 6 public string Genre { get; set; } 7 public decimal Price { get; set; } 8 public string Rating { get; set; } 9 }
步驟2:重新生成項目,更改View
1)改 \Views\Movies\index.html
1 @model IEnumerable<MvcMovie.Models.Movie> 2 3 @{ 4 ViewBag.Title = "Index"; 5 } 6 7 <h2>Index</h2> 8 9 <p> 10 @Html.ActionLink("Create New", "Create") 11 </p> 12 <table> 13 <tr> 14 <th> 15 @Html.DisplayNameFor(model => model.Title) 16 </th> 17 <th> 18 @Html.DisplayNameFor(model => model.ReleaseDate) 19 </th> 20 <th> 21 @Html.DisplayNameFor(model => model.Genre) 22 </th> 23 <th> 24 @Html.DisplayNameFor(model => model.Price) 25 </th> 26 <th> 27 @Html.DisplayNameFor(model => model.Rating) 28 </th> 29 <th></th> 30 </tr> 31 32 @foreach (var item in Model) { 33 <tr> 34 <td> 35 @Html.DisplayFor(modelItem => item.Title) 36 </td> 37 <td> 38 @Html.DisplayFor(modelItem => item.ReleaseDate) 39 </td> 40 <td> 41 @Html.DisplayFor(modelItem => item.Genre) 42 </td> 43 <td> 44 @Html.DisplayFor(modelItem => item.Price) 45 </td> 46 <td> 47 @Html.DisplayFor(modelItem => item.Rating) 48 </td> 49 <td> 50 @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | 51 @Html.ActionLink("Details", "Details", new { id=item.ID }) | 52 @Html.ActionLink("Delete", "Delete", new { id=item.ID }) 53 </td> 54 </tr> 55 } 56 57 </table>
2)改 \Views\Movies\Create.html
1 @model MvcApplication1.Models.Movie 2 3 @{ 4 ViewBag.Title = "Create"; 5 } 6 7 <h2>Create</h2> 8 9 @using (Html.BeginForm()) { 10 @Html.AntiForgeryToken() 11 @Html.ValidationSummary(true) 12 13 <fieldset> 14 <legend>Movie</legend> 15 16 <div class="editor-label"> 17 @Html.LabelFor(model => model.Title) 18 </div> 19 <div class="editor-field"> 20 @Html.EditorFor(model => model.Title) 21 @Html.ValidationMessageFor(model => model.Title) 22 </div> 23 24 <div class="editor-label"> 25 @Html.LabelFor(model => model.ReleaseDate) 26 </div> 27 <div class="editor-field"> 28 @Html.EditorFor(model => model.ReleaseDate) 29 @Html.ValidationMessageFor(model => model.ReleaseDate) 30 </div> 31 32 <div class="editor-label"> 33 @Html.LabelFor(model => model.Genre) 34 </div> 35 <div class="editor-field"> 36 @Html.EditorFor(model => model.Genre) 37 @Html.ValidationMessageFor(model => model.Genre) 38 </div> 39 40 <div class="editor-label"> 41 @Html.LabelFor(model => model.Price) 42 </div> 43 <div class="editor-field"> 44 @Html.EditorFor(model => model.Price) 45 @Html.ValidationMessageFor(model => model.Price) 46 </div> 47 48 <div class="editor-label"> 49 @Html.LabelFor(model=>model.Rating) 50 </div> 51 52 <div class="editor-field"> 53 @Html.EditorFor(model=>model.Rating) 54 @Html.ValidationMessageFor(model=>model.Rating) 55 </div> 56 <p> 57 <input type="submit" value="Create" /> 58 </p> 59 </fieldset> 60 } 61 62 <div> 63 @Html.ActionLink("Back to List", "Index") 64 </div> 65 66 @section Scripts { 67 @Scripts.Render("~/bundles/jqueryval") 68 }
這時,編譯並運行網站,會出現一個錯誤:
提示MovieDBContext更改,和數據庫不匹配。
可以有下面多種途徑解決這個錯誤:
1)使用Entity Framework 自動刪除、並基於新的model class 架構 重建數據庫。如果在測試數據庫上使用這種方式非常方便。然而,不適合應用到已經有大量數據的數據庫上,因為重建會丟失所有原有數據。
Using an initializer to automatically seed a database with test data is often a productive way to develope an application. For more information on Entity Framework database initializers, see Tom Dykstra's ASP.NET MVC/Entity Framework tutorial.
2)更改數據庫結構,以匹配model類架構。
這種方式的優勢是可以保留數據庫原有記錄。可以手動更改,也可以編寫數據庫更新腳本代碼
3)使用 Code First 遷移(Code First Migrations)來更新數據庫架構。
這時我們當前這篇博文使用的方式。
步驟3:使用Code First Migrations 來更新數據庫架構:
1)首先打開 \Migrations\Configuration.cs 文件,為每個Movie臨時對象添加Rating字段:
1 protected override void Seed(MvcApplication1.Models.MovieDBContext context) 2 { 3 // This method will be called after migrating to the latest version. 4 5 // You can use the DbSet<T>.AddOrUpdate() helper extension method 6 // to avoid creating duplicate seed data. E.g. 7 // 8 // context.People.AddOrUpdate( 9 // p => p.FullName, 10 // new Person { FullName = "Andrew Peters" }, 11 // new Person { FullName = "Brice Lambson" }, 12 // new Person { FullName = "Rowan Miller" } 13 // ); 14 // 15 context.Movies.AddOrUpdate(i => i.Title, 16 new Movie 17 { 18 Title = "When Harry Met Sally", 19 ReleaseDate = DateTime.Parse("1989-1-11"), 20 Genre = "Romantic Comedy", 21 Rating = "G", 22 Price = 7.99M 23 }, 24 25 new Movie 26 { 27 Title = "Ghostbusters ", 28 ReleaseDate = DateTime.Parse("1984-3-13"), 29 Genre = "Comedy", 30 Rating = "G", 31 Price = 8.99M 32 }, 33 34 new Movie 35 { 36 Title = "Ghostbusters 2", 37 ReleaseDate = DateTime.Parse("1986-2-23"), 38 Genre = "Comedy", 39 Rating = "G", 40 Price = 9.99M 41 }, 42 43 new Movie 44 { 45 Title = "Rio Bravo", 46 ReleaseDate = DateTime.Parse("1959-4-15"), 47 Genre = "Western", 48 Rating = "G", 49 Price = 3.99M 50 }); 51 }
2)打開程序包管理器控制台中輸入命令
add-migration AddRatingMig
如圖:
這句命令是添加一個遷移更改,並將其命名為"AddRatingMig".
會自動檢查當前的Model框架,比對數據庫,生成一個加有時間戳命名的遷移代碼:
如上圖,代碼中包含一個Up()和Down()方法
3)重新生成項目,並打開程序包管理器控制台中輸入命令
update-database
更新數據庫架構,如圖:
4)運行
可以在首頁(index)和create中發現新加入的Rating列
但是Edit和Detail中還沒有,那是因為我們只處理了index.cshtml和create.cshtml,讀者可以自行試着模仿前面的操作改動Edit.cshtml和Detail.cshtml、SearchIndex
初學MS 的MVC 4,參照微軟www.asp.net/mvc 中的入門項目,寫個MVC 4的入門系列,以供復習和分享。
微軟入門項目:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4
【目錄】
1.[.NET MVC4 入門系列01]Helloworld MVC 4 第一個MVC4程序
2. [.NET MVC4 入門系列02]MVC Movie 為項目添加Model
3. [.NET MVC4 入門系列03]使用Controller訪問Model中數據
4. [.NET MVC4 入門系列04]Controller和View間交互原理
5. .NET MVC4 入門系列05]添加自定義查詢頁Search
6. [.NET MVC4 入門系列06] 在Movie Model和表中添加新字段(Code First Migrations)
7. [.NET MVC4 入門系列07] 在Model模型模塊中添加驗證