[翻译][MVC 5 + EF 6] 3:排序、过滤、分页
原文:Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application
1.添加排序:
1.1.修改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());
}
1.2.修改Views\Student\Index.cshtml:
<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>
效果图:

2.添加搜索框:
2.1.修改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.Contains(searchString)
|| s.FirstMidName.Contains(searchString));
}
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());
}
在大多数情况下,我们调用同一个方法时,在EF实体集和内存中集合的扩展方法返回的结果是一样的;但是在一些情况下返回结果会不一样。
例如当传递一个空的字符串时.NET Framework的Contains方法返回所有行,但是SQL Server Compact 4.0的EF 提供者(provider)的Contains返回0行。因此上面的代码中把Where语句放在if语句中,以保证对所有的SQL Server版本返回相同的数据。同样,.NET Framework的Contains方法默认是区分大小写的,因此,使用ToUpper方法将字符串显示转换为大写以确保以后代码改为仓储时(返回类型由IQueryable类型变成IEnumerable类型)返回结果不会发生变化(当调用Contains方法返回IEnumerable集合时,调用的是.NET Framework实现;返回IQueryable对象时,调用的是数据库提供者的实现)。
当我们返回IQueryable对象时,不同的数据库提供者对空值的处理也不同。例如,在有些脚本中where条件中的table.Column != 0可能不会返回空值列。
2.2.为Views\Student\Index.cshtml添加搜索框:
<p>
@Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm())
{
<p>
Find by name: @Html.TextBox("SearchString")
<input type="submit" value="Search" />
</p>
}
效果图:

3.添加分页:
3.1.安装PagedList.MVC:
Install-Package PagedList.Mvc
3.2.修改Controllers\StudentController.cs:
using PagedList;
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 = ;
}
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.Contains(searchString)
|| s.FirstMidName.Contains(searchString));
}
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
students = students.OrderBy(s => s.LastName);
break;
} int pageSize = ;
int pageNumber = (page ?? );
return View(students.ToPagedList(pageNumber, pageSize));
}
当页面第一次加载或者用户没有点击分页或排序链接时,所有的参数都是空值。
ViewBag.CurrentSort用于点击分页时保存排序信息。
ViewBag.CurrentFilter用于保存搜索信息,并且当页面刷新时给搜索框赋值。当搜索条件改变时,page值重置为1。
3.3.修改Views\Student\Index.cshtml:
@model PagedList.IPagedList<ContosoUniversity.Models.Student>
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" /> @{
ViewBag.Title = "Students";
} <h2>Students</h2> <p>
@Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
<p>
Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
<table class="table">
<tr>
<th>
@Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
First Name
</th>
<th>
@Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th></th>
</tr> @foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.FirstMidName)
</td>
<td>
@Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
@Html.ActionLink("Details", "Details", new { id=item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
} </table>
<br />
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount @Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
BeginForm提交form数据的默认方式是post,post方式是通过HTTP消息体而不是通过URL查询字符串传递参数。我们通过FormMethod.Get把它指定为HTTP GET,这样用户就可以将URL收藏为书签。当动作不会导致更新时W3C HTTP GET使用指南推荐我们使用GET。
效果图:

4.添加About页面展示Student统计信息:
4.1.创建视图模型:
新建ViewModels文件夹EnrollmentDateGroup.cs:
public class EnrollmentDateGroup
{
[DataType(DataType.Date)]
public DateTime? EnrollmentDate { get; set; } public int StudentCount { get; set; }
}
4.2.修改HomeController.cs:
private SchoolContext db = new SchoolContext();
//...
public ActionResult About()
{
IQueryable<EnrollmentDateGroup> data = from student in db.Students
group student by student.EnrollmentDate into dateGroup
select new EnrollmentDateGroup()
{
EnrollmentDate = dateGroup.Key,
StudentCount = dateGroup.Count()
};
return View(data.ToList());
}
//...
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
4.3.修改Views\Home\About.cshtml:
@model IEnumerable<ContosoUniversity.ViewModels.EnrollmentDateGroup>
@{
ViewBag.Title = "Student Body Statistics";
}
<h2>Student Body Statistics</h2>
<table>
<tr>
<th>
Enrollment Date
</th>
<th>
Students
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
<td>
@item.StudentCount
</td>
</tr>
}
</table>
效果图:

[翻译][MVC 5 + EF 6] 3:排序、过滤、分页的更多相关文章
- asp.net core 排序过滤分页组件:sieve(1)
使用asp.net core开发时避免不了要用一个合适的分页组件来让前端获取分页数据.github上面有一个开源的分页组件在这方面很适合我的使用,于是我把他的文档翻译一下,随后会分析它里面的源码.这是 ...
- [翻译][MVC 5 + EF 6] 12[完结]:高级场景
原文:Advanced Entity Framework 6 Scenarios for an MVC 5 Web Application 1.执行原生SQL查询: EF Code First API ...
- [翻译][MVC 5 + EF 6] 11:实现继承
原文:Implementing Inheritance with the Entity Framework 6 in an ASP.NET MVC 5 Application 1.选择继承映射到数据库 ...
- [翻译][MVC 5 + EF 6] 10:处理并发
原文:Handling Concurrency with the Entity Framework 6 in an ASP.NET MVC 5 Application 1.并发冲突: 当一个用户编辑一 ...
- [翻译][MVC 5 + EF 6] 9:异步和存储过程
原文:Async and Stored Procedures with the Entity Framework in an ASP.NET MVC Application 1.为什么使用异步代码: ...
- [翻译][MVC 5 + EF 6] 8:更新相关数据
原文:Updating Related Data with the Entity Framework in an ASP.NET MVC Application 1.定制Course的Create和E ...
- [翻译][MVC 5 + EF 6] 7:加载相关数据
原文:Reading Related Data with the Entity Framework in an ASP.NET MVC Application 1.延迟(Lazy)加载.预先(Eage ...
- [翻译][MVC 5 + EF 6] 6:创建更复杂的数据模型
原文:Creating a More Complex Data Model for an ASP.NET MVC Application 前面的教程中,我们使用的是由三个实体组成的简单的数据模型.在本 ...
- [翻译][MVC 5 + EF 6] 5:Code First数据库迁移与程序部署
原文:Code First Migrations and Deployment with the Entity Framework in an ASP.NET MVC Application 1.启用 ...
随机推荐
- Configuring Active Directory Federation Services 2.0 (配置 adfs 2.0) -摘自网络
Active Directory Federation Services (AD FS) 2.0 makes it possible to deploy a federation server and ...
- redis的hash, list, set类型相关命令
hash相关命令: 1. hset HSET key field value 将哈希表key中的域field的值设为value.如果key不存在,一个新的哈希表被创建并进行hset操作.如果域fiel ...
- 建立树莓派raspberry交叉编译环境以及编译内核
最近买了一个树莓派,玩了几天,虽然已经有很多人玩了,现在玩好像有点晚了,但是他确实是个好东西,学好它,对嵌入式的整个开发流程也就会熟悉很多.虽然性能不是很强和现在的BB-BLACK比有点慢了,但是它便 ...
- 用VerbalExpressions来帮助我们写正则表达式
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:用VerbalExpressions来帮助我们写正则表达式.
- Enum枚举类|注解Annotation
Enum枚举类 ①枚举类和普通类的差别: 使用 enum 定义的枚举类默认继承了 java.lang.Enum 类 枚举类的构造器仅仅能使用 private 訪问控制符 枚举类的全部实例必须在枚举类中 ...
- zend studio-字体大小设置
在使用zend studio的过程中为了方便我们编码,很多时候需要设置编码的字体的大小,设置步骤如下: 选择[Windows]-[preference]-[general]-[appearance]- ...
- SpringMVC + ehcache( ehcache-spring-annotations)基于注解的服务器端数据缓存
背景 声明,如果你不关心java缓存解决方案的全貌,只是急着解决问题,请略过背景部分. 在互联网应用中,由于并发量比传统的企业级应用会高出很多,所以处理大并发的问题就显得尤为重要.在硬件资源一定的情况 ...
- [Whole Web, Node.js, PM2] Restarting your node.js app on code change using pm2
Aadd watch to the config.json file: { "apps": [{ "name": "App1", " ...
- Spring3.0官网文档学习笔记(八)--3.4.3~3.4.6
3.4.3 使用depends-on 使用depends-on能够强制使一个或多个beans先初始化,之后再对这个bean进行初始化. 多个bean之间用","." ...
- IIS7及以上伪静态报错404
内容摘要:故障现象:DTCMS开启伪静态功能,VS2010预览正常,发布到IIS后报错404.0错误(WIN7,WIN8,SERVER2008).模块IISWebCore通知MapRequestHan ...