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

Rick Anderson

注意

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

在本節中,您將使用 Entity Framework Code First 移轉 將一些變更移轉至模型類別,以便將變更套用至資料庫。

根據預設,當您使用 Entity Framework Code First 自動建立資料庫時,如同您稍早在本教學課程中所做的一樣,Code First 會將數據表新增至資料庫,以協助追蹤資料庫的架構是否與產生的模型類別同步。 如果它們未同步,Entity Framework 會擲回錯誤。 這可讓您更輕鬆地在開發時間追蹤您可能只在運行時間發現(透過模糊錯誤)的問題。

設定模型變更 Code First 移轉

如果您使用 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 檔案。 Seed使用下列程式代碼取代 Configuration.cs 檔案中的 方法:

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;

注意

Seed Code First 移轉 在每次移轉之後呼叫 方法(也就是在 封裝管理員 控制台中呼叫 update-database),而且此方法會更新已經插入的數據列,或如果數據列還不存在,則會加以插入。

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

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

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

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

Code First 移轉 會在 中建立另一個類別檔案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。 種子數據隨即顯示。

顯示 [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 會指示移轉架構使用目前電影 DB 架構檢查目前的電影模型,並建立必要的程式代碼,以將資料庫移轉至新的模型。 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。 您可以看到新的 [評等] 欄位。

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

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

7_CreateRioII

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

7_ourNewMovie_SM

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

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

在本節中,您已瞭解如何修改模型物件,並讓資料庫與變更保持同步。 您也已瞭解如何使用範例數據填入新建立的資料庫,以便試用案例。 接下來,讓我們看看如何將更豐富的驗證邏輯新增至模型類別,並啟用某些商務規則的強制執行方式。