5.1 从控制器访问模型中的数据
在本节中,我们将创建一个新的MoviesController类,并且书写代码来获取数据库中的数据,并通过视图模板来显示在浏览器中。
鼠标右击Controller文件夹,点击“添加”菜单下的“控制器”菜单项,将会弹出一个“添加控制器”对话框,如图5-1所示
图 5-1 添加控制器
在该对话框中将控制器命名为MoviesController,然后点击添加按钮,该对话框被关闭。观察解决方案资源管理器重,Controllers文件夹下增加了一个名为MoviesController.cs的文件,并且呈打开状态。让我们更新MoviesController类中的Index方法,以便获取movie(电影)清单。
这里需要注意的是,为了引用我们前面创建的MovieDBContext类,你需要在文件头部追加如下所示的两个using语句。
using MvcMovie.Models;
using System.Linq;
修改MoviesController类中的代码为代码清单5-1中所示代码
代码清单5-1MoviesController类中的完整代码
using MvcMovie.Models;
using System.Linq;
using System;
using System.Web.Mvc;
namespace MvcMovie.Controllers
{
public class MoviesController:Controller
{
MovieDBContext db=new MovieDBContext();
public ActionResult Index()
{
var movies=from m in db.Movies
where m.ReleaseDate>new DateTime(1984,6,1)
select m;
return View(movies.ToList());
}
}
}
这段代码实施了一个LINQ查询来获取1984年夏天之后发行的所有电影。我们还需要一个视图模板来显示这个电影清单,所以在Index方法内点击鼠标右键,然后点击“添加视图”来添加一个视图。
由于这里我们需要将一个Movie类传递给视图,所以在“添加视图”对话框中,与本教程中前几次在该对话框中之行的操作有所不同,前几次我们都是直接点击添加按钮来创建一个空白的视图模板,但是这一次我们想让Visual Web Developer 为我们自动创建一个具有一些默认处理的强类型的视图,所以我们勾选“创建强类型视图”复选框,在模型类下拉框中选择“Movie(MvcMovie.Models)”(如果模型类中不存在这个类,请先点击调试菜单下的“生成MvcMovie”生成该类,)在支架模板下拉框中选择“List”,最后勾选“引用脚本”复选框,如图5-2所示。
图 5-2 添加强类型视图
点击添加按钮,Visual Web Developer自动生成一个视图,并且自动在视图文件中添加显示电影清单所需要的代码。这里,我们首先用与前面修改HelloWorld控制器所用的视图中的标题同样的方法来修改这个Movies控制器所用视图中的标题。
代码清单5-2为修改后的这个视图中的完整代码。在这段代码中,我们将releaseDate(发行日期)属性的格式化字符串从原来的“{0:g}”修改为“{0:d}”(长日期修改为短日期),将Price(票价)属性的格式化字符串从原来的“{0:F}”修改为“{0:c}”(float类型修改为货币类型)。
另外,将列表标题中的文字全部修改为中文名称。
代码清单5-2Movies控制器所用视图中的完整代码
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title="电影清单";
}
<h2>我的电影清单</h2>
<p>
@html.ActionLink("追加","Create")
</p>
<table>
<tr>
<th></th>
<th>电影名称</th>
<th>发行日期</th>
<th>种类</th>
<th>票价</th>
</tr>
@foreach (var item in Model){
<tr>
<td>
@Html.ActionLink("编辑","Edit",new{id=item.ID}) |
@Html.ActionLink("查看明细","Details",new{id=item.ID}) |
@Html.ActionLink("删除","Delete",new{id=item.ID}) |
@Html.ActionLink("编辑","Edit",new{id=item.ID})
</td>
<td>@item.Title</td>
<td>@String.Format("{0:d}",item.ReleaseDate)</td>
<td>@item.Genre</td>
<td>@String.Format("{0:c2}",item.Price)</td>
</tr>
}
</table>
5.2强类型模型与@model关键字
在本教程的前文中,我们介绍了一个控制器可以使用ViewBag对象来将数据或对象传递到视图模板中。ViewBag是一个动态对象,它提供了一种便利的,后期绑定的方法来将信息从控制器传递到视图中。
ASP.NET MVC也提供了一种利用强类型的方法来将数据或对象传递到视图模板中。这种强类型的方法为你的编码过程提供了很丰富的编辑时的智能输入提示信息与非常好的编译时的检查。接下来我们将结合这种方法与我们的Movies控制器(MoviesController)与视图模板(Index.cshtml)一起使用。
请注意在我们的MoviesController控制器的Index方法中,我们在调用View()方法时传入了一个参数,代码如下所示。
public class MoviesController:Controller
{
MovieDBContext db=new MovieDBContext();
public ActionResult Index()
{
var movies=from m in db.Movies
where m.ReleaseDate>new DateTime(1984,6,1)
select m;
return View(movies.ToList());
}
}
请注意如下这一行代码表示将一个movies列表从控制器传递到了视图中。
return View(movies.ToList());
通过在视图模板文件的头部使用@model语句,视图模板可以识别传入的参数中的对象类型是否该试题模板所需要的对象类型。请记住当我们在创建这个Movies控制器所使用的模板时,我们在“添加视图”对话框总勾选了“创建强类型视图”复选框,在模型下拉框中选择了“Movie(MvcMovie.Models)”,在支架模板下拉框中选择了“List”。所以Visual Web Developer自动在我们的视图模板文件的第一行中添加了如下所示的语句。
@model IEnumerable<MvcMovie.Models.Movie>
@model关键字允许我们在视图模板中直接访问在控制器类中通过使用强类型的“模型”而传递过来的Movie类的列表。例如,在我们的Index.cshtml视图模板中,我们可以通过foreach语句来便利这强类型的模型,访问其中的每一个Movie对象。代码如下所示。
@foreach (var item in Model){
<tr>
<td>
@Html.ActionLink("编辑","Edit",new {id=item.ID})
@Html.ActionLink("查看明细","Details",new {id=item.ID})
@Html.ActionLink("删除","Delete",new {id=item.ID})
</td>
<td>@item.Title</td>
<td>@String.Format("{0:d}",item.ReleaseDate)</td>
<td>@item.Genre</td>
<td>@String.Format("{0:c2}",item.Price)</td>
</tr>
}
因为这里的“模型”是强类型的(IEnumerable<Movie>),所以在循环遍历是“模型”中的每一个项目(“item”)也是一个强类型的Movie对象,可以直接访问该对象的每一个属性。同时这也意味着我们可以在编译时检查我们的代码,同时在书写代码时也可以使用代码编辑器提供的智能输入提示信息,如图5-3所示。
图 5-3 可以使用强类型“模型”所带来的智能输入提示信息
5.3与SQL Server Express结合使用
我们在本节前面创建了一个MovieDBContext类,用来连接数据库,并将数据库中的记录映射到Movie对象。你也许会问一个问题,怎么定义数据库连接?接下来我们通过在web.config文件中增加一些连接信息来定义一个数据库的连接。
打开应用程序根目录下的Web.config文件(请注意不是Views文件夹下的Web.config文件),如图5-4所示。
图 5-4 打开应用程序根目录下的Web.config文件
在Web.config文件的<connectionStrings>元素中追加类似如下所示的连接字符串。
<configuration>
<connectionStrings>
<add name="ApplicationServices"
connectiongString="data source=.\SQLEXPRESS;Integrated
Security=SSPI;AttachDBFilename=|DataDirectory | aspnetdb.mdf;
User Instance=true"
providerName="System.Data.SqlClient"/>
<add name="MovieDBContext"
connectionString="Data Source=.\SQLEXPRESS;
Initial Catalog=Movie;Persist Security Info=True;
User ID=aaa;Password=aaaa"
providerName="System.Data.SqlClient"/>
</connectionStrings>
connectionString属性的值表示我们想要使用SQL Server Express的一个本地实例中的Movies数据库。当你安装Visual Web Developer Express的时候,安装过程中也会同时自动在你的计算机中安装SQL Server Express,你可以利用它来进行有关数据库的管理工作。
运行应用程序,在浏览器中输入“http://localhost:xxxx/Movies”,浏览器中将会显示一张空的电影列表,如图5-5所示。
图 5-5 数据库中没有数据时将默认显示空的列表
EF code-first如果发现使用我们提供的连接字符串而连接到数据库中没有“Movies”数据库,它将自动为我们创建一个。你可以在类似“C:\Program Files\Microsoft SQL\MSSQL10.SQLEXPRESS\MSSQL\DATA”这样的SQL Server的安装目录下去查看是否该数据库已被创建。
另外请注意,在本教程的前面部分中,我们采用如下所示的代码创建了一个Movies模型。
using System;
using System.Data.Entity;
namespace MvcMovie.Models
{
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 class MovieDBContext:DbContext
{
public DbSet<Movie> Movies {get;set;}
}
}
如您所见,当我们第一次使用MoviesController控制器来访问MovieDBContext所指向的实例是,Entity Framework可以自动为你创建一个新的Movies数据库,并且将MovieDBContext类的Movies属性映射到一个新的Movies表,并且自动将它创建。这个表中的每一行被映射到一个新的Movie类的实例,Movies表的每一列被映射到Movie类的一个属性。
你 可以使用SQL Server Management Studio 来查看使用模型创建处理的数据库与数据表。
在Windwos的开始菜单中打开SQL Server Management Studio,并且连接到Web.config中所配置的数据库,如图5-6所示。
图 5-6 使用SQL Server Management Studio连接数据库
点击“连接”按钮进行连接,查看数据库,可以看见Movies数据库与数据表已被创建,如图5-7所示。
图片 5-7 Movies数据库与数据表已被创建
鼠标右键Movies数据表,并且点击“设计“,如图5-8所示。
图 5-8 点击“设计”查看Movies表的属性
你可以看见Movies表中各字段的属性,其中ID字段被自动设定为自增长主键,如图5-9中所示。
图 5-9 查看Movies表中各字段属性
这里请注意Movies表中各字段是如何映射到Movie类中各属性上的。Entity Framework code-first自动在你创建的Movie类的基础上创建了这张Movies数据表。
你现在已经可以访问数据库中的Movies数据表,并且有了一个简单的页面来显示这个表中的内容。在下一节,我们将增加一个追加数据的方法和一个追加数据的视图,并且向数据库中追加一些数据。