共用方式為


將新欄位新增至電影模型和資料表

Rick Anderson

注意

這裡提供本教學課程的更新版本,其中使用 ASP.NET MVC 5 和 Visual Studio 2013。 新的教學指示更安全、更易於遵循且示範更多功能。

在本節,您會使用 Entity Framework Code First Migrations 將部分變更移轉至模型類別,以便讓變更套用至資料庫。

根據預設,使用 Entity Framework Code First 來自動建立資料庫時 (正如稍早在本教學課程操作的動作),Code First 會將表格新增至資料庫,以協助追蹤資料庫的結構描述是否與它產生的來源模型類別同步。 如果未同步,Entity Framework 會擲回錯誤。 這可讓您更輕鬆地在開發階段追蹤您可能只會在執行階段 (透過不明的錯誤) 發現的問題。

為模型變更設定 Code First Migrations

如果您使用 Visual Studio 2012,請按兩下 方案總管 中的Movies.mdf檔案,以開啟資料庫工具。 Visual Studio Express for Web 會顯示 [資料庫總管],Visual Studio 2012 會顯示 [伺服器總管]。 如果您使用 Visual Studio 2010,請使用 SQL Server 物件總管。

在資料庫工具中(資料庫總管、伺服器總管或 SQL Server 物件總管),以滑鼠右鍵單擊MovieDBContext並選取 [刪除] 以卸除電影資料庫。

顯示 [伺服器總管] 視窗的螢幕快照。已選取 [電影 D B 內容] 右鍵選單中的 [刪除]。

流覽回 方案總管。 以滑鼠右鍵按一下 Movies.mdf 檔案,然後選取 [刪除] 移除電影資料庫。

顯示 [方案總管] 視窗的螢幕快照。在 [電影] 點 m d f 右鍵功能表中選取 [刪除]。

建立應用程式,確認沒有任何錯誤。

[工具] 功能表按一下 [NuGet 套件管理員],然後按一下 [套件管理員主控台]

新增套件管理員

提示字元的 [封裝管理員 控制台] 視窗中PM>,輸入 「Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext」。

顯示 [封裝管理員 主控台] 視窗的螢幕快照。輸入 [啟用移轉] 命令。

Enable-Migrations 命令 (如上所示) 會在新的 Migrations 資料夾中建立 Configuration.cs 檔案。

顯示 [方案總管] 視窗的螢幕快照。Migrations 資料夾和 Configuration dot c 檔案會以紅色圓形。

Visual Studio 會 開啟 Configuration.cs 檔案。 將 Configuration.cs 檔案的 Seed 方法取代為下列程式碼:

protected override void Seed(MvcMovie.Models.MovieDBContext context)
{
    context.Movies.AddOrUpdate( i => i.Title,
        new Movie
        {
            Title = "When Harry Met Sally",
            ReleaseDate = DateTime.Parse("1989-1-11"),
            Genre = "Romantic Comedy",
            Price = 7.99M
        },

         new Movie
         {
             Title = "Ghostbusters ",
             ReleaseDate = DateTime.Parse("1984-3-13"),
             Genre = "Comedy",
             Price = 8.99M
         },

         new Movie
         {
             Title = "Ghostbusters 2",
             ReleaseDate = DateTime.Parse("1986-2-23"),
             Genre = "Comedy",
             Price = 9.99M
         },

       new Movie
       {
           Title = "Rio Bravo",
           ReleaseDate = DateTime.Parse("1959-4-15"),
           Genre = "Western",
           Price = 3.99M
       }
   );
   
}

以滑鼠右鍵按下下方Movie的紅色波浪線,然後選取 [解析],然後使用MvcMovie.Models;

顯示 [影片] 右鍵功能表中已選取 [解析] 的螢幕快照。

這樣做會新增下列 using 陳述式:

using MvcMovie.Models;

注意

Code First Migrations 會在每次移轉後 (也就是在套件管理員主控台呼叫 update-database) 呼叫 Seed 方法,且此方法會更新已插入的列,如果列尚不存在則直接插入。

按 CTRL-SHIFT-B 建置專案。(如果您目前未建置,下列步驟將會失敗。

下個步驟是建立初始移轉的 DbMigration 類別。 此移轉會建立新的資料庫,這就是您在 上一個步驟中刪除movie.mdf 檔案的原因。

[封裝管理員 控制台] 視窗中,輸入 “add-migration Initial” 命令以建立初始移轉。 「Initial」是用來命名已建立的移轉檔案的任意名稱。

顯示 [主控台] 視窗 封裝管理員 螢幕快照。此移轉檔案之設計工具程式代碼開頭的段落會反白顯示。

Code First Migrations 會在 Migrations 資料夾中建立另一個類別檔案 (名稱為 {DateStamp}_Initial.cs),且此類別包含的程式碼會建立資料庫結構描述。 移轉檔案名稱的前綴包含時間戳記,有助排序。 檢查 {DateStamp}_Initial.cs檔案,其中包含為Movie DB 建立Movies資料表的指示。 如果您在下方指示更新資料庫,此 {DateStamp}_Initial.cs 檔案就會執行並建立資料庫結構描述。 然後,Seed 方法會執行以便在資料庫填入測試資料。

封裝管理員 主控台中,輸入命令 「update-database」 以建立資料庫並執行 Seed 方法。

顯示 [封裝管理員 主控台] 視窗的螢幕快照。輸入更新資料庫命令。

如果您收到錯誤,指出表格已存在且無法建立,可能是因為您在刪除資料庫之後及執行 update-database 之前執行應用程式。 在此情況下,請再次刪除 Movies.mdf 檔案,然後重試 update-database 命令。 如果仍然收到錯誤,請刪除移轉資料夾和內容,然後開始操作此頁面頂端的指示 (也就是刪除 Movies.mdf 檔案,然後繼續啟用移轉)。

執行應用程式,並前往 /Movies URL。 Seed 資料隨即顯示。

顯示 [M V C 電影索引] 頁面的螢幕快照,其中包含四部電影的清單。

將 Rating 屬性新增至電影模型

首先,新增 Rating 屬性至現有的 Movie 類別。 開啟 Models\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; }
}

使用 [建置電影] 功能表命令或按 CTRL-SHIFT-B 來建>置應用程式。

現在您已更新 類別Model,您也需要更新 \Views\Movies\Index.cshtml 和 \Views\Movies\Create.cshtml 檢視範本,才能在瀏覽器檢視中顯示新的Rating屬性。

開啟\Views\Movies\Index.cshtml 檔案,並在 Price 數據行後面新增數據<th>Rating</th>行標題。 然後,在範本結尾附近新增數 <td> 欄來轉譯 @item.Rating 值。 以下為 Index.cshtml 檢視範本更新後的外觀:

@model IEnumerable<MvcMovie.Models.Movie>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Price)
        </th>
         <th>
            @Html.DisplayNameFor(model => model.Rating)
        </th>
        <th></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", "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 資料行)。

有幾個方法可以解決這個錯誤:

  1. 讓 Entity Framework 自動卸除資料庫,並重新依據新的模型類別結構描述來建立資料庫。 在測試資料庫上執行主動式開發時,此方法非常方便;它可讓您快速發展模型和資料庫架構。 不過,這麼做的缺點是您會遺失資料庫現有的資料,因此不建議對生產資料庫使用此方法! 使用初始化表達式自動植入具有測試數據的資料庫,通常是開發應用程式的生產力方式。 如需 Entity Framework 資料庫初始化表達式的詳細資訊,請參閱 Tom Dykstra 的 ASP.NET MVC/Entity Framework 教學課程
  2. 您可明確修改現有資料庫的結構描述,使其符合模型類別。 這種方法的優點是可以保留您的資料。 您可以手動方式或藉由建立資料庫變更指令碼來進行這項變更。
  3. 使用 Code First 移轉來更新資料庫結構描述。

在本教學課程中,我們將使用 Code First 移轉。

更新 Seed 方法,讓它為新的欄提供值。 開啟 Migrations\Configuration.cs 檔案,並將 Rating 欄位新增至每個 Movie 物件。

new Movie
{
    Title = "When Harry Met Sally",
    ReleaseDate = DateTime.Parse("1989-1-11"),
    Genre = "Romantic Comedy",
    Rating = "G",
    Price = 7.99M
},

建立解決方案,然後開啟「套件管理員主控台」視窗,輸入下列命令:

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” 命令

下圖顯示 [封裝管理員 控制台] 視窗中的輸出(AddRatingMig 前面加上的日期戳記將會不同。

顯示更新資料庫命令的螢幕快照。

重新執行應用程式,並前往 /Movies URL。 您可以看到新的「Rating」欄位。

顯示 [M V C 電影索引] 頁面的螢幕快照,其中列出四部電影。

按一下 [新建] 連結以新增新電影。 請注意,您已可以新增評分。

7_CreateRioII

按一下 [建立]。 新的電影 (包括評分) 現在會在電影清單中顯示:

7_ourNewMovie_SM

您也應該將 Rating 欄位新增至 [編輯]、[詳細數據] 和 [搜尋][索引] 檢視範本。

您可以在 [封裝管理員 控制台] 視窗中再次輸入 “update-database” 命令,而且不會進行任何變更,因為架構符合模型。

在本節中,您已瞭解如何修改模型物件,並讓資料庫與變更維持同步。 您也已藉由範例資料的試用案例,瞭解如何將資料填入新建的資料庫。 接下來,我們會說明如何在模型類別中新增更豐富的驗證邏輯,並啟用可強制執行的商務規則。