將新欄位新增至電影模型和資料表 (C#)
注意
這裡提供本教學課程的更新版本,其中使用 ASP.NET MVC 5 和 Visual Studio 2013。 新的教學指示更安全、更易於遵循且示範更多功能。
本教學課程將說明基本概念,簡介如何使用 Microsoft Visual Web Developer 2010 Express Service Pack 1 (Visual Studio Microsoft 的免費版本) 建置 ASP.NET MVC Web 應用程式。 開始之前,請確定您已安裝下列必要項目。 您可按以下連結安裝所有專案:Web Platform Installer。 或者可使用下列連結個別安裝必要條件:
- Visual Studio Web Developer Express SP1 必要條件
- ASP.NET MVC 3 工具更新
- SQL Server Compact 4.0 (執行階段 + 工作支援)
如果您使用 Visual Studio 2010 而非 Visual Web Developer 2010,請按以下連結安裝必要條件:Visual Studio 2010 必要條件。
本主題隨附內含 C# 原始程式碼的 Visual Web Developer 專案。 下載 C# 版本。 如果您偏好使用 Visual Basic,請切換至本教學課程的 Visual Basic version 版。
在本節中,您將對模型類別進行一些變更,並瞭解如何配合這些變更來更新資料庫架構。
將 Rating 屬性新增至電影模型
首先,新增 Rating
屬性至現有的 Movie
類別。 開啟「Movie.cs」檔案並新增 Rating
屬性,如下所示:
public string Rating { get; set; }
完成的 Movie
類別現在看起來類似下列程式碼:
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
public string Rating { get; set; }
}
使用 [偵錯] > [建置電影] 功能表命令,重新編譯應用程式。
現在您已更新 Model
類別,接著也需要更新 \Views\Movies\Index.cshtml 和 \Views\Movies\Create.cshtml 檢視範本,以支援新的 Rating
屬性。
開啟 \Views\Movies\Index.cshtml 檔案,並在 Price 資料行後方新增 <th>Rating</th>
行標題。 然後,在範本結尾附近新增數 <td>
欄來轉譯 @item.Rating
值。 以下為 Index.cshtml 檢視範本更新後的外觀:
<table>
<tr>
<th></th>
<th>Title</th>
<th>Release Date</th>
<th>Genre</th>
<th>Price</th>
<th>Rating</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.Rating )
</td>
<td>
@Html.ActionLink("Edit Me", "Edit", new { id=item.ID }) |
@Html.ActionLink("Details", "Details", new { id=item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
接下來,開啟 \Views\Movies\Create.cshtml 檔案,並在表單結尾附近新增下列標記。 此可呈現文字方塊,讓您在建立新電影時指定評分。
<div class="editor-label">
@Html.LabelFor(model => model.Rating)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Rating)
@Html.ValidationMessageFor(model => model.Rating)
</div>
管理模型和資料庫架構差異
您現在已更新應用程式的程式碼,可支援新的 Rating
屬性。
現在請執行應用程式,並前往 /Movies URL。 不過執行此操作時,會遇到下列錯誤:
您會看到此錯誤,是因為應用程式中更新的 Movie
模型類別已經與現有資料庫的 Movie
資料表結構描述不同。 (資料庫資料表中沒有任何 Rating
資料行)。
根據預設,使用 Entity Framework Code First 自動建立資料庫時 (稍早在本教學課程執行的步驟),Code First 會將資料表新增至資料庫,協助追蹤資料庫的結構描述是否與產生的來源模型類別同步。 如果未同步,Entity Framework 會擲回錯誤。 這樣在開發階段就可更輕鬆地追蹤原本只能在執行階段 (透過不明的錯誤) 發現的問題。 因為同步檢查功能,所以您才會看到錯誤訊息。
有兩個方法可以解決這個錯誤:
- 讓 Entity Framework 自動卸除資料庫,並重新依據新的模型類別結構描述來建立資料庫。 這個方法可讓您一併調整模型和資料庫結構描述,快速又方便,非常適合在實際開發測試資料庫時採用。 不過,缺點是會遺失資料庫中現有的資料,因此不建議對實際執行中的資料庫使用此方法!
- 您可明確修改現有資料庫的結構描述,使其符合模型類別。 這種方法的優點是可以保留您的資料。 您可以手動方式或藉由建立資料庫變更指令碼來進行這項變更。
在本教學課程中,我們會採取第一種方法,也就是任何時候只要模型變更,Entity Framework Code First 就會自動重新建立資料庫。
模型變更時自動重新建立資料庫
我來來更新應用程式,確保 Code First 在您變更應用程式的模型時,會自動捨棄並重新建立資料庫。
注意
警告!只有在使用開發或測試資料庫時,才啟用自動捨棄和重新建立資料庫,且絕不用於內含實際資料的實際執行資料庫。 若用在實際執行的伺服器,可能會導致資料遺失。
在 [方案總管] 中,以滑鼠右鍵按一下 Models 資料夾,選取 [新增],然後選取 [類別]。
將類別命名為「MovieInitializer」。 將 MovieInitializer
類別更新為包含下列程式碼:
using System;
using System.Collections.Generic;
using System.Data.Entity;
namespace MvcMovie.Models {
public class MovieInitializer : DropCreateDatabaseIfModelChanges<MovieDBContext> {
protected override void Seed(MovieDBContext context) {
var movies = new List<Movie> {
new Movie { Title = "When Harry Met Sally",
ReleaseDate=DateTime.Parse("1989-1-11"),
Genre="Romantic Comedy",
Rating="R",
Price=7.99M},
new Movie { Title = "Ghostbusters ",
ReleaseDate=DateTime.Parse("1984-3-13"),
Genre="Comedy",
Rating="R",
Price=8.99M},
new Movie { Title = "Ghostbusters 2",
ReleaseDate=DateTime.Parse("1986-2-23"),
Genre="Comedy",
Rating="R",
Price=9.99M},
new Movie { Title = "Rio Bravo",
ReleaseDate=DateTime.Parse("1959-4-15"),
Genre="Western",
Rating="R",
Price=3.99M},
};
movies.ForEach(d => context.Movies.Add(d));
}
}
}
MovieInitializer
類別指定,若模型類別經過變更,則該模型使用的資料庫應自動捨棄並重新建立。 程式碼包含 Seed
方法,可指定預設資料,以在建立資料庫時自動新增至資料庫 (或重新建立)。 這可讓您將範例資料填入資料庫,不用每次變更模型時再手動填入,非常實用。
現在您已定義 MovieInitializer
類別,接著要來進行連接,這樣每次應用程式執行時,系統才能檢查模型類別是否與資料庫中的結構描述不同。 如果有所不同,您可執行初始設定式,根據模型重新建立資料庫,然後使用範例資料填入資料庫。
開啟位於 MvcMovies
專案根目錄的「Global.asax」檔案:
「Global.asax」檔案包含類別,用於定義專案的整個應用程式,並包含應用程式初次啟動時執行的事件處理常式 Application_Start
。
在檔案頂端新增兩個 using 陳述式。 第一個參照 Entity Framework 命名空間,第二個參照 MovieInitializer
類別所在的命名空間:
using System.Data.Entity; // Database.SetInitialize
using MvcMovie.Models; // MovieInitializer
然後尋找 Application_Start
方法,並將呼叫新增至方法開頭的 Database.SetInitializer
,如下所示:
protected void Application_Start()
{
Database.SetInitializer<MovieDBContext>(new MovieInitializer());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
您剛才新增的 Database.SetInitializer
陳述式指出,如果結構描述和資料庫不符,則 MovieDBContext
執行個體使用的資料庫應自動刪除並重新建立。 如您所見,這也會在資料庫中填入已於 MovieInitializer
類別指定的範例資料。
關閉「Global.asax」檔案。
重新執行應用程式,並瀏覽至 /Movies URL。 應用程式啟動時,會偵測到模型結構不再符合資料庫結構描述。 這將自動重新建立資料庫,以符合新的模型結構,並使用範例電影填入資料庫:
按一下 [新建] 連結以新增電影。 請注意,您已可以新增評分。
按一下 [建立]。 新的電影 (包括評分) 現在會在電影清單中顯示:
在本節中,您已瞭解如何修改模型物件,並讓資料庫與變更維持同步。 您也已藉由範例資料的試用案例,瞭解如何將資料填入新建的資料庫。 接下來,我們會說明如何在模型類別中新增更豐富的驗證邏輯,並啟用可強制執行的商務規則。