作者: 里克·安德森
注意
此处提供了本教程的更新版本,它使用 ASP.NET MVC 5 和 Visual Studio 2013。 它更安全,更易于遵循并演示更多功能。
本教程将介绍如何使用 Microsoft Visual Web Developer 2010 Express Service Pack 1 生成 ASP.NET MVC Web 应用程序的基本知识,这是 visual Studio 的免费 Microsoft版本。 在开始之前,请确保已安装下面列出的先决条件。 可以通过单击以下链接来安装所有这些组件: Web 平台安装程序。 或者,可使用以下链接单独安装各个必备软件:
如果使用 Visual Studio 2010 而不是 Visual Web Developer 2010,请单击以下链接安装必备组件: Visual Studio 2010 先决条件。
带有 C# 源代码的 Visual Web 开发人员项目随本主题一起提供。 下载 C# 版本。 如果更喜欢 Visual Basic,请切换到 本教程的 Visual Basic 版本 。
在本部分中,你将对模型类进行一些更改,并了解如何更新数据库架构以匹配模型更改。
向电影模型添加分级属性
首先向 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 自动丢弃,并基于新的模型类架构重新创建数据库。 在测试数据库上执行活动开发时,此方法非常方便,因为它允许你快速发展模型和数据库架构。 不过,缺点是,在数据库中丢失现有数据,因此 你不想 在生产数据库中使用此方法!
- 对现有数据库架构进行显式修改,使它与模型类相匹配。 此方法的优点是可以保留数据。 可以手动或通过创建数据库更改脚本进行此更改。
在本教程中,我们将使用第一种方法 — 只要模型发生更改,就会自动重新创建实体框架代码。
在模型更改时自动重新创建数据库
让我们更新应用程序,以便每当更改应用程序的模型时,Code First 会自动删除并重新创建数据库。
注意
警告 :仅当使用开发或测试数据库时,才应启用此方法来自动删除和重新创建数据库,而 不要 对包含实际数据的生产数据库启用此方法。 在生产服务器上使用它可能会导致数据丢失。
在解决方案资源管理器中,右键单击“模型”文件夹,选择“添加”,然后选择“类”。
将类命名为“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。 应用程序启动时,它会检测到模型结构不再与数据库架构匹配。 它会自动重新创建数据库以匹配新的模型结构,并使用示例电影填充数据库:
单击“新建”链接添加新电影。 请注意,可以添加分级。
单击 “创建” 。 新电影,包括评级,现在显示在电影列表:
本部分介绍了如何修改模型对象,并使数据库与更改保持同步。 你还了解了使用示例数据填充新创建的数据库的方法,以便可以试用方案。 接下来,让我们看看如何向模型类添加更丰富的验证逻辑,以及如何强制实施一些业务规则。