原文: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:排序、过滤、分页的更多相关文章

  1. asp.net core 排序过滤分页组件:sieve(1)

    使用asp.net core开发时避免不了要用一个合适的分页组件来让前端获取分页数据.github上面有一个开源的分页组件在这方面很适合我的使用,于是我把他的文档翻译一下,随后会分析它里面的源码.这是 ...

  2. [翻译][MVC 5 + EF 6] 12[完结]:高级场景

    原文:Advanced Entity Framework 6 Scenarios for an MVC 5 Web Application 1.执行原生SQL查询: EF Code First API ...

  3. [翻译][MVC 5 + EF 6] 11:实现继承

    原文:Implementing Inheritance with the Entity Framework 6 in an ASP.NET MVC 5 Application 1.选择继承映射到数据库 ...

  4. [翻译][MVC 5 + EF 6] 10:处理并发

    原文:Handling Concurrency with the Entity Framework 6 in an ASP.NET MVC 5 Application 1.并发冲突: 当一个用户编辑一 ...

  5. [翻译][MVC 5 + EF 6] 9:异步和存储过程

    原文:Async and Stored Procedures with the Entity Framework in an ASP.NET MVC Application 1.为什么使用异步代码: ...

  6. [翻译][MVC 5 + EF 6] 8:更新相关数据

    原文:Updating Related Data with the Entity Framework in an ASP.NET MVC Application 1.定制Course的Create和E ...

  7. [翻译][MVC 5 + EF 6] 7:加载相关数据

    原文:Reading Related Data with the Entity Framework in an ASP.NET MVC Application 1.延迟(Lazy)加载.预先(Eage ...

  8. [翻译][MVC 5 + EF 6] 6:创建更复杂的数据模型

    原文:Creating a More Complex Data Model for an ASP.NET MVC Application 前面的教程中,我们使用的是由三个实体组成的简单的数据模型.在本 ...

  9. [翻译][MVC 5 + EF 6] 5:Code First数据库迁移与程序部署

    原文:Code First Migrations and Deployment with the Entity Framework in an ASP.NET MVC Application 1.启用 ...

随机推荐

  1. POJ2407–Relatives(欧拉函数)

    题目大意 给定一个正整数n,要求你求出所有小于n的正整数当中与n互质的数的个数 题解 欧拉函数模板题~~~因为n过大~~~所以直接用公式求 代码: #include<iostream> # ...

  2. 最短路变形 poj3615&

    问题: 牛要跨过一些障碍,希望以最小的体力跨过障碍,并且对于一条路径,只在乎其中最高的障碍. 输入N代表站点数,标记为1—N,输入M代表路径数,从站点S到E之间需要跨过高度为H的障碍. 输入T代表牛要 ...

  3. SAP 使用SQL Trace(ST05)

    SAP 使用SQL Trace(ST05) SAP R/3 提供标准ABAP SQL 跟踪工具.使用T-Code:ST05 可以进入追踪设定画面:          在Trace Modes 区域中选 ...

  4. Python自动安装第三方类库

    Python在使用过程中会用到大量的第三方库,逐一手工去下载.安装比较繁琐.可以配置第三方镜像源并使用pip进行自动安装.这里推荐选择豆瓣的镜像源:http://pypi.douban.com/sim ...

  5. UML类图中类与类的四种关系图解

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  6. FindStringExact

          Code:: CComboBox::FindStringExact int FindStringExact( int nIndexStart, LPCTSTR lpszFind ) con ...

  7. Lua代码解析-写给C和C++开发人员

    lua语言作为一门轻量级脚本语言,能够非常好的被嵌入到应用程序,因此,在移动游戏开发中举足轻重 然后C/C++开发人员转lua并非非常习惯,我也是..所以,一起努力学习lua吧 lua没有类的概念,有 ...

  8. android97 播放音频 有进度条控制

    package com.itheima.musicplayer; import android.os.Bundle; import android.os.Handler; import android ...

  9. 第一个html程序

    <html><head><title> 表单</title> </head><body><form action=&quo ...

  10. Java synchronized 总结

    在Java开发的时候经常会用到关键字synchronized来对代码进行同步,在使用的过程中,对于synchronized确不是很熟悉,最近在看Spring源码时,发现有不少地方都用到同步,因此,趁此 ...