EntityFramework_MVC4中EF5 新手入门教程之三 ---3.排序、 筛选和分页
在前面的教程你实施了一套基本的 CRUD 操作,为Student
实体的 web 页。在本教程中,您将添加排序、 筛选和分页到 StudentsIndex的功能。您还将创建一个页面,并简单分组。
下面的插图显示页面当你完成时的样子。列标题是链接,用户可以单击要作为排序依据的列。单击列标题,一再升序和降序之间切换。
将列排序链接添加到学生索引页
若要添加排序到学生索引页,会改变Student
控制器的Index
方法,将代码添加到Student
的索引视图。
添加排序功能指数法
在Controllers\StudentController.cs,用下面的代码替换该Index
的方法:
public ActionResult Index(string sortOrder)
{
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date_desc" : "Date";
var students = from s in db.Students
select s;
switch (sortOrder)
{
case "Name_desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "Date":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "Date_desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.LastName);
break;
}
return View(students.ToList());
}
这段代码接收sortOrder
参数从 URL 中的查询字符串。由 ASP.NET MVC 作为操作方法的参数提供的查询字符串值。该参数将是"名称"日期",(可选) 其次是下划线和"desc"来指定降序排序字符串的字符串。默认的排序顺序升序。
第一次请求的索引页时,那里是没有查询字符串。学生按升序排列显示的LastName
,这是默认值,秋天通过案switch
语句所认定。当用户单击列标题的超链接时,在查询字符串中提供了适当sortOrder
值。
两个ViewBag
变量使用这样的视图可以使用适当的查询字符串值配置列标题的超链接:
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date_desc" : "Date";
这些都是三元的语句。第一个指定sortOrder
参数为 null 或为空,是否ViewBag.NameSortParm
应设置为"name_desc";否则,应将设置为空字符串。这两个语句使该视图设置列标题的超链接,如下所示:
当前排序顺序 | 最后一个名称超链接 | 日期的超链接 |
---|---|---|
Last Name升序排列 | 降序 | 升序 |
Last Name降序 | 升序 | 升序 |
Date升序 | 升序 | 降序 |
Date降序 | 升序 | 升序 |
该方法使用LINQ to 实体来指定要作为排序依据的列。代码创建IQueryable变量switch
语句之前,修改在switch
语句,并ToList
调用后switch
语句。当您创建和修改IQueryable
变量时,没有查询发送到数据库中。不执行查询,直到您将IQueryable
对象转换成一个集合通过调用一种方法如ToList
。因此,这段代码结果中的单个查询,return View
的语句之前不会被执行。
添加列标题到学生的索引视图的超链接
在Views\Student\Index.cshtml,将标题行的<tr>
和<th>
元素替换突出显示的代码:
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
@Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
</th>
<th>First Name
</th>
<th>
@Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
此代码使用ViewBag
属性中的信息来设置适当的查询字符串值的超链接。
运行此页,然后单击Last Name和Enrollment Date的列标题,以验证该文献整理工作。
单击姓氏标题后,学生是降序显示最后一个名称。
向学生索引页添加一个搜索框
若要添加筛选到学生索引页,将会向视图中添加一个文本框和一个提交按钮和Index
方法中做相应的修改。文本框中会让你输入名字和姓氏字段中搜索的字符串。
将筛选功能添加到索引方法
在Controllers\StudentController.cs,用下面的代码 (突出显示所做的更改) 来替换Index
方法:
public ViewResult Index(string sortOrder, string searchString)
{
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
var students = from s in db.Students
select s;
if (!String.IsNullOrEmpty(searchString))
{
students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
|| s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "name_desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "Date":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "date_desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.LastName);
break;
}
return View(students.ToList());
}
您已经添加到Index
方法的searchString
参数。您已经添加在 LINQ 语句where
clausethat 选择只有其名字或姓氏包含搜索字符串的学生。搜索字符串值被收到一个文本框,您将添加到索引视图。 添加where子句的语句执行只有在要搜索的值。
注在许多情况下你可以调用同一个方法,在实体框架的实体集或作为一种对内存中集合的扩展方法。结果通常都是一样,但在某些情况下可能会有所不同。例如,Contains
方法的.NET 框架实现返回的所有行时将为空字符串传递给它,但 SQL Server 紧凑 4.0 的实体框架提供程序都返回零行空字符串。因此 (放Where
中if
语句的语句) 的示例中的代码将确保你得到相同的结果,所有版本的 SQL Server。而且在此基础上, Contains
方法的.NET 框架实现默认情况下,执行区分大小写的比较,实体框架 SQL Server 提供程序在默认情况下执行不区分大小写的比较。因此,调用ToUpper
方法使测试明确不区分大小写可以确保当您更改以后要使用的存储库,它将返回而不是IQueryable
对象IEnumerable
集合的代码结果不会改变。(当Contains
调用对IEnumerable
集合时,你得到的.NET 框架实现 ; 当你对IQueryable
对象调用它,你得到的数据库提供程序实现。
学生的索引视图中添加一个搜索框
在Views\Student\Index.cshtml,添加突出显示的代码之前开放table
标记以创建一个标题、 一个文本框和搜索按钮。
<p>
@Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm())
{
<p>
Find by name: @Html.TextBox("SearchString")
<input type="submit" value="Search" /></p>
}
<table>
<tr>
运行该页面,输入搜索字符串,单击搜索筛选验证正常工作。
请注意 URL 不包含"一个"搜索字符串,这意味着如果用书签标记此页,你不会得到筛选后的列表,当您使用该书签。您将更改搜索按钮,稍后在本教程中使用查询字符串进行筛选条件。
将分页添加到学生index页
要向学生索引页添加分页,你会开始通过安装PagedList.Mvc NuGet 程序包。然后你会在Index
法进行其他更改和添加分页链接到Index
视图。PagedList.Mvc是一个多好的分页和排序包为 ASP.NET MVC 中,和它的使用在这里仅用作示例,不是为它在其他选项的建议。下面的插图显示分页链接。
安装 PagedList.MVC NuGet 程序包
NuGet PagedList.Mvc包自动安装PagedList软件包,作为一种依赖。PagedList程序包安装IQueryable
和IEnumerable
收藏PagedList
集合类型和扩展方法。扩展方法在您IQueryable
或IEnumerable
, PagedList
集合中创建单个数据页和PagedList
集合提供了若干属性和便利分页的方法。PagedList.Mvc包安装一个分页的助手显示分页按钮。
从工具菜单中,选择库程序包管理器,然后管理 NuGet 程序包的解决方案.
在管理 NuGet 程序包对话框中,单击联机选项卡在左边,然后在搜索框中输入"paged"。当你看到PagedList.Mvc包时,单击安装.
在选择项目框中,单击确定.
将分页功能添加到索引方法
在Controllers\StudentController.cs,添加PagedList
命名空间的using
语句:
using PagedList;
用下面的代码来替换Index
方法:
public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var students = from s in db.Students
select s;
if (!String.IsNullOrEmpty(searchString))
{
students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
|| s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "name_desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "Date":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "date_desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default: // Name ascending