从控制器访问数据模型

最后更新于:2022-04-01 16:29:19

在本节中,您将创建一个新的`MoviesController`类,并在这个Controller类里编写代码来取得电影数据,并使用视图模板将数据展示在浏览器里。 在开始下一步前,先Build一下应用程序(**生成应用程序)**(确保应用程序编译没有问题) 在**解决方案**上,用鼠标右键单击Controller文件夹,点击**新增**,再选择**Controller**。 [![clip_image002](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b58d665.jpg "clip_image002") ](http://images.cnitblog.com/blog/139239/201401/211505014225.jpg) 在**Scaffold新增**对话框,选择**MVC 5  Controller with views, using Entity Framework,**点击**新增。** [![clip_image004](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b5a24f8.gif "clip_image004") ](http://images.cnitblog.com/blog/139239/201401/211505053133.gif) · 控制器(Controller)名称输入: **MoviesController**. · 模型类(Model class)选择: **Movie (MvcMovie.Models)**. · 数据上下文类(Data context class)选择:**MovieDBContext (MvcMovie.Models)** 下图显示了完成的对话框。 [![clip_image006](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b5bc52b.gif "clip_image006") ](http://images.cnitblog.com/blog/139239/201401/211505089534.gif) 单击**添加(**如果你得到一个错误,则很可能**增加控制器前**,没有生成该应用程序)。Visual Studio Express 会创建以下文件和文件夹: · 项目控制器文件夹中的*MoviesController.cs*文件。 · 项目视图文件夹下的 Movie文件夹。 · 在新的Views\Movies*文件夹中创建Create.cshtml、 Delete.cshtml、 Details.cshtml、 Edit.cshtml*和*Index.cshtml* 文件。 Visual Studio自动创建 [CRUD](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete)(创建、 读取、 更新和删除) 操作方法,和相关的视图文件(CRUD 自动创建的操作方法和视图文件被称为 **scaffolding**)。 现在您有了可以创建、列表、 编辑和删除电影Entity 所有的Web功能了。 运行应用程序,通过将/Movies追加到浏览器地址栏 URL的后面,从而浏览Movies控制器。因为应用程序依赖于默认路由 (*App_Start\RouteConfig.cs* 文件中的定义),浏览器请求*http://localhost:xxxxx/Movies*将被路由到`Movies`控制器默认的`Index` 操作方法。换句话说,浏览器请求*http://localhost:xxxxx/Movies*等同于浏览器请求*http://localhost:xxxxx/Movies/Index*。因为您还没有添加任何内容,所以结果是一个空的电影列表。 [![clip_image008](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b5d35ad.jpg "clip_image008") ](http://images.cnitblog.com/blog/139239/201401/211505102669.jpg) **创建电影** 点击**Create New**链接。输入有关电影的一些详细信息,然后单击**Create**按钮。 [![clip_image010](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b5e3dcc.gif "clip_image010") ](http://images.cnitblog.com/blog/139239/201401/211505116090.gif) **注意**:您可能无法在“价格”字段中输入小数点或逗号。要支持非英语语言环境,小数点用逗号(","),和非美国英语的日期格式的jQuery验证,你必须包括globalize.js,和你的具体文化/ globalize.cultures.js的文件(从[https://github.com/jquery/globalize](https://github.com/jquery/globalize))和JavaScript使用Globalize.parseFloat的。在接下来的教程中,我将展示如何做到这一点。现在,只需输入整数,如10。 单击**Create**按钮将使得窗体提交至服务器,同时电影信息也会保存到数据库里,然后您会被重定向到/Movies 的URL,您可以在列表中看到刚刚创建的新电影。 [![clip_image012](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b5f41c6.gif "clip_image012") ](http://images.cnitblog.com/blog/139239/201401/211505135787.gif) 创建一些更多的电影数据(movie entries)。 同时也可以尝试点击**编辑**、**详细信息**和**删除**功能的链接。 #### 看一下生成的代码 打开*Controllers\MoviesController.cs*文件,并找到生成的`Index`方法。一部分电影控制器和`Index`方法如下所示。 publicclass MoviesController : Controller{private MovieDBContext db = new MovieDBContext();// GET: /Movies/public ActionResult Index() {return ~~~ View(db.Movies.ToList()); } ~~~ 向`Movies`控制器请求,从而返回`Movies`电影数据库表中的所有记录,然后将结果传递给`Index`视图。下面是MoviesController类中实例化电影数据库上下文实例,如前面所述。电影数据库上下文实例可用于查询、 编辑和删除的电影。 private MovieDBContext db =new MovieDBContext(); #### 强类型模型和 @model 关键字 在本系列前面教程中,您看到了使用`ViewBag`对象,从控制器传递数据或对象给视图模板。`ViewBag`是一个动态的对象,提供了方便的后期绑定(late-bound)方法将信息传递给视图。 MVC 还提供了传递强类型对象(strongly typed objects)到视图模板的能力。这种强类型使得更好的在编译时检查您的代码, 并在Visual Studio 编辑器中提供更加丰富的[智能感知](http://msdn.microsoft.com/en-us/library/hcw1s69b(v=vs.120).aspx)([IntelliSense](http://msdn.microsoft.com/en-us/library/hcw1s69b(v=vs.120).aspx))。 当创建操作方法和视图时, Visual Studio 中的scaffolding机制(也就是通过一个强类型的模型)使用了`MoviesController`类和视图模板。 在*Controllers\MoviesController.cs*文件中看一下生成的`Details`方法。电影控制器里的`Details`方法如下所示。 public ActionResult Details(int? id) {if (id == null) {returnnew HttpStatusCodeResult(HttpStatusCode.BadRequest); } Movie movie= db.Movies.Find(id);if (movie == null) { return HttpNotFound(); }return ~~~ View(movie); } ~~~ id参数一般是通过路由数据传递. 例如 [http://localhost:1234/movies/details/1](http://localhost:1234/movies/details/1) 会设置电影控制器的控制,该方法操作details并设置id为1。 你也可以通过一个查询字符串(query string) 的id如下: http://localhost:1234/movies/details?id=1 如果查找到了一个`Movie`,`Movie` 模型的实例会传递给Detail视图。 return View(movie); 看一下Views\Movies\Details.cshtml文件里的内容。 @model MvcMovie.Models.Movie @{ ViewBag.Title = "Details"; }<h2>Details</h2><div><h4>Movie</h4><hr /><dl class="dl-horizontal"><dt> ~~~ @Html.DisplayNameFor(model => model.Title) ~~~ </dt> ~~~ @*Markup omitted for clarity.*@ ~~~ </dl></div><p> ~~~ @Html.ActionLink("Edit", "Edit", new { id = Model.ID }) | @Html.ActionLink("Back to List", "Index") ~~~ </p> 通过引入视图模板文件顶部的`@model`语句,您可以指定该视图期望的对象类型。当您创建电影控制器时,Visual Studio 会将`@model`声明自动包含到*Details.cshtml*文件的顶部: @model MvcMovie.Models.Movie 此`@model`声明使得控制器可以将强类型的`Model`对象传递给View视图, 从而您可以在视图里访问传递过来的强类型电影Model。 例如,在*Details.cshtml*模板中,每部电影的字段,通过代码传递了`DisplayNameFor` 和[DisplayFor](http://msdn.microsoft.com/en-us/library/system.web.mvc.html.displayextensions.displayfor(VS.98).aspx) HTML Helper通过强类型的`Model`对象。Create和Edit方法还有视图模板都在传递电影的强类型模型对象。 看一下*Index.cshtml*视图模版和*MoviesController.cs*中的`Index` 方法。请注意这些代码是如何在I`ndex`操作方法中,创建[`List`](http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx)对象,并调用`View`方法的。 此代码在控制器中传递`Movies`列表给视图: ~~~ public ActionResult Index() { return View(db.Movies.ToList()); } ~~~ 当您创建电影控制器时,Visual Studio会自动包含 `@model`语句到*Index.cshtml*文件的顶部 @model IEnumerable<MvcMovie.Models.Movie> 此`@model`声明使得控制器可以将强类型的电影列表`Model`对象传递给View视图。例如,在*Index.cshtml*模板中,在强类型的`Model`对象上使用`foreach`语句循环遍历电影列表: @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><th> ~~~ @Html.DisplayFor(modelItem => item.Rating) ~~~ </th><td> ~~~ @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | @Html.ActionLink("Details", "Details", { id=item.ID }) | @Html.ActionLink("Delete", "Delete", { id=item.ID }) ~~~ </td></tr> ~~~ } ~~~ 因为`Model`对象是强类型的 (是`IEnumerable<Movie>`对象),所以在循环中的每个`item`对象的类型是`Movie`类型。好处之一是,这意味着您可以在代码编译时进行检查,同时在代码编辑器中支持更加全面的智能感知: [![clip_image002[4]](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b6124bf.jpg "clip_image002[4]") ](http://images.cnitblog.com/blog/139239/201401/211505156419.jpg) #### 使用SQL Server LocalDB Entity Framework Code First(代码优先),如果检测到不存在一个数据库连接字符串指向了`Movies`数据库,会自动的创建数据库。在*App_Data*文件夹中找一下,您可以验证它已经被创建了。如果您看不到*Movies.mdf*文件,请在**解决方案资源管理器**工具栏上,单击**显示所有文件**按钮,单击**刷新**按钮,然后展开App_Data文件夹。 [![clip_image004](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b626ce0.jpg "clip_image004") ](http://images.cnitblog.com/blog/139239/201401/211505177037.jpg) 双击*Movies.mdf*打开**数据库资源管理器(SERVER EXPLORER)**,然后展开**表**文件夹(Tables) 以查看电影表。 **注意**:ID旁边的钥匙图标。默认情况下,EF将创建一个名为ID的主键。欲了解更多EF和MVC信息,请参阅Tom Dykstra's的优秀教程[MVC and EF](http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application)。 [![clip_image006](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b63a462.jpg "clip_image006") ](http://images.cnitblog.com/blog/139239/201401/211505226562.jpg) 在Movies表上单击鼠标右键,并请选择显示表数据(**Show Table Data**)看您所创建的数据。 [![clip_image008[4]](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b6480e1.jpg "clip_image008[4]") ](http://images.cnitblog.com/blog/139239/201401/211505243287.jpg) [![clip_image010[4]](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b658d0f.gif "clip_image010[4]") ](http://images.cnitblog.com/blog/139239/201401/211505267347.gif) 在Movies表上单击鼠标右键,并请选择打开表定义(**Open Table Definition**), 您将看到Entity Framework Code First创建的表结构。 [![clip_image011](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b670259.jpg "clip_image011") ](http://images.cnitblog.com/blog/139239/201401/211505288445.jpg) [![clip_image013](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b6b7938.jpg "clip_image013") ](http://images.cnitblog.com/blog/139239/201401/211505308597.jpg) 注意事项: Movies表映射到Movie类的架构(schema)如何你前面创建的。Entity Framework Code First首先自动为您创造了这个架构(schema)基于Movie class。当您完成后,通过右击MovieDBContext,并选择关闭连接。 (如果你不关闭连接,下一次运行项目,你可能会得到一个错误)。 [![clip_image015](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-02_568736b6cfb9b.jpg "clip_image015") ](http://images.cnitblog.com/blog/139239/201401/211505340001.jpg) 现在,您可以在这个简单列表页面里:显示、编辑、更新、删除数据库里的数据了。在下一次的教程中,我们会继续看看scaffolded自动生成的其它代码。并添加一个`SearchIndex`方法和`SearchIndex`视图,使您可以在数据库中搜索电影了。更多关于Entity Framework with MVC, see[Creating an Entity Framework Data Model for an ASP.NET MVC Application](http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application).
';