將新欄位新增至影片模型和資料庫資料表 (VB)
本教學課程將說明基本概念,簡介如何使用 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 必要條件。
本主題隨附內含 VB.NET 原始程式碼的 Visual Web Developer 專案。 下載 VB.NET 版本。 如果您偏好使用 C#,請改參閱本教學課程的 C# 版。
在本節中,您將對模型類別進行一些變更,並瞭解如何配合這些變更來更新資料庫架構。
將 Rating 屬性新增至電影模型
首先,新增 Rating
屬性至現有的 Movie
類別。 開啟「Movie.cs」檔案並新增 Rating
屬性,如下所示:
Public Property Rating() As String
完成的 Movie
類別現在看起來類似下列程式碼:
Public Class Movie
Public Property ID() As Integer
Public Property Title() As String
Public Property ReleaseDate() As Date
Public Property Genre() As String
Public Property Price() As Decimal
Public Property Rating() As String
End Class
使用 [偵錯] > [建置電影] 功能表命令,重新編譯應用程式。
現在您已更新 類別Model
,您也需要更新 \Views\Movies\Index.vbhtml 和 \Views\Movies\Create.vbhtml 檢視範本,以支援新的Rating
屬性。
開啟\Views\Movies\Index.vbhtml 檔案,並在 Price 數據行後面新增數據<th>Rating</th>
行標題。 然後,在範本結尾附近新增數 <td>
欄來轉譯 @item.Rating
值。 以下是更新 的 Index.vbhtml 檢視範本外觀:
<table>
<tr>
<th> Title </th>
<th> ReleaseDate </th>
<th> Genre </th>
<th> Price </th>
<th>Rating</th>
<th></th>
</tr>
@For Each item In Model
Dim currentItem = item
@<tr>
<td>
@Html.DisplayFor(Function(modelItem) currentItem.Title)
</td>
<td>
@Html.DisplayFor(Function(modelItem) currentItem.ReleaseDate)
</td>
<td>
@Html.DisplayFor(Function(modelItem) currentItem.Genre)
</td>
<td>
@Html.DisplayFor(Function(modelItem) currentItem.Price)
</td>
<td>
@Html.DisplayFor(Function(modelItem) currentItem.Rating)
</td>
<td>
@Html.ActionLink("Edit", "Edit", New With {.id = currentItem.ID}) |
@Html.ActionLink("Details", "Details", New With {.id = currentItem.ID}) |
@Html.ActionLink("Delete", "Delete", New With {.id = currentItem.ID})
</td>
</tr>
Next
</table>
接下來,開啟 \Views\Movies\Create.vbhtml 檔案,並在窗體結尾附近新增下列標記。 此可呈現文字方塊,讓您在建立新電影時指定評分。
<div class="editor-label">
@Html.LabelFor(Function(model) model.Rating)
</div>
<div class="editor-field">
@Html.EditorFor(Function(model) model.Rating)
@Html.ValidationMessageFor(Function(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;
Imports System
Imports System.Collections.Generic
Imports System.Data.Entity
Namespace MvcMovie.Models
Public Class MovieInitializer
Inherits DropCreateDatabaseIfModelChanges(Of MovieDBContext)
Protected Overrides Sub Seed(ByVal context As MovieDBContext)
Dim movies = New List(Of Movie) From {
New Movie With {.Title = "When Harry Met Sally", .ReleaseDate = Date.Parse("1989-1-11"), .Genre = "Romantic Comedy", .Rating = "R", .Price = 7.99D},
New Movie With {.Title = "Ghostbusters ", .ReleaseDate = Date.Parse("1984-3-13"), .Genre = "Comedy", .Rating = "R", .Price = 8.99D},
New Movie With {.Title = "Ghostbusters 2", .ReleaseDate = Date.Parse("1986-2-23"), .Genre = "Comedy", .Rating = "R", .Price = 9.99D},
New Movie With {.Title = "Rio Bravo", .ReleaseDate = Date.Parse("1959-4-15"), .Genre = "Western", .Rating = "R", .Price = 3.99D}}
movies.ForEach(Function(d) context.Movies.Add(d))
End Sub
End Class
End Namespace
MovieInitializer
類別指定,若模型類別經過變更,則該模型使用的資料庫應自動捨棄並重新建立。 程式碼包含 Seed
方法,可指定預設資料,以在建立資料庫時自動新增至資料庫 (或重新建立)。 這可讓您將範例資料填入資料庫,不用每次變更模型時再手動填入,非常實用。
現在您已定義 MovieInitializer
類別,接著要來進行連接,這樣每次應用程式執行時,系統才能檢查模型類別是否與資料庫中的結構描述不同。 如果有所不同,您可執行初始設定式,根據模型重新建立資料庫,然後使用範例資料填入資料庫。
開啟位於 MvcMovies
專案根目錄的「Global.asax」檔案:
「Global.asax」檔案包含類別,用於定義專案的整個應用程式,並包含應用程式初次啟動時執行的事件處理常式 Application_Start
。
Application_Start
尋找 方法,並在 方法開頭新增 對 的呼叫Database.SetInitializer
,如下所示:
Sub Application_Start()
System.Data.Entity.Database.SetInitializer(Of MovieDBContext)(New MvcMovie.Models.MovieInitializer())
AreaRegistration.RegisterAllAreas()
RegisterGlobalFilters(GlobalFilters.Filters)
RegisterRoutes(RouteTable.Routes)
End Sub
您剛才新增的 Database.SetInitializer
陳述式指出,如果結構描述和資料庫不符,則 MovieDBContext
執行個體使用的資料庫應自動刪除並重新建立。 如您所見,這也會在資料庫中填入已於 MovieInitializer
類別指定的範例資料。
關閉「Global.asax」檔案。
重新執行應用程式,並瀏覽至 /Movies URL。 應用程式啟動時,會偵測到模型結構不再符合資料庫結構描述。 這將自動重新建立資料庫,以符合新的模型結構,並使用範例電影填入資料庫:
按一下 [新建] 連結以新增電影。 請注意,您已可以新增評分。
按一下 [建立]。 新的電影 (包括評分) 現在會在電影清單中顯示:
在本節中,您已瞭解如何修改模型物件,並讓資料庫與變更維持同步。 您也已藉由範例資料的試用案例,瞭解如何將資料填入新建的資料庫。 接下來,我們會說明如何在模型類別中新增更豐富的驗證邏輯,並啟用可強制執行的商務規則。