共用方式為


將新欄位新增至電影模型和資料表 (C#)

作者:Rick Anderson

注意

這裡提供本教學課程的更新版本,其中使用 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 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 會擲回錯誤。 這樣在開發階段就可更輕鬆地追蹤原本只能在執行階段 (透過不明的錯誤) 發現的問題。 因為同步檢查功能,所以您才會看到錯誤訊息。

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

  1. 讓 Entity Framework 自動卸除資料庫,並重新依據新的模型類別結構描述來建立資料庫。 這個方法可讓您一併調整模型和資料庫結構描述,快速又方便,非常適合在實際開發測試資料庫時採用。 不過,缺點是會遺失資料庫中現有的資料,因此不建議對實際執行中的資料庫使用此方法!
  2. 您可明確修改現有資料庫的結構描述,使其符合模型類別。 這種方法的優點是可以保留您的資料。 您可以手動方式或藉由建立資料庫變更指令碼來進行這項變更。

在本教學課程中,我們會採取第一種方法,也就是任何時候只要模型變更,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 dot asax dot c s] 索引標籤的螢幕擷取畫面。[方案總管] 視窗中的 Global dot 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。 應用程式啟動時,會偵測到模型結構不再符合資料庫結構描述。 這將自動重新建立資料庫,以符合新的模型結構,並使用範例電影填入資料庫:

7_MyMovieList_SM

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

7_CreateRioII

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

7_ourNewMovie_SM

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