原文:Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application

1.添加排序

1.1.修改Controllers\StudentController.cs的Index:

  1. public ActionResult Index(string sortOrder)
  2. {
  3. ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
  4. ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
  5. var students = from s in db.Students
  6. select s;
  7. switch (sortOrder)
  8. {
  9. case "name_desc":
  10. students = students.OrderByDescending(s => s.LastName);
  11. break;
  12. case "Date":
  13. students = students.OrderBy(s => s.EnrollmentDate);
  14. break;
  15. case "date_desc":
  16. students = students.OrderByDescending(s => s.EnrollmentDate);
  17. break;
  18. default:
  19. students = students.OrderBy(s => s.LastName);
  20. break;
  21. }
  22. return View(students.ToList());
  23. }

1.2.修改Views\Student\Index.cshtml

  1. <p>
  2. @Html.ActionLink("Create New", "Create")
  3. </p>
  4. <table>
  5. <tr>
  6. <th>
  7. @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
  8. </th>
  9. <th>First Name
  10. </th>
  11. <th>
  12. @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })
  13. </th>
  14. <th></th>
  15. </tr>

  效果图:

2.添加搜索框

2.1.修改Controllers\StudentController.cs的Index:

  1. public ViewResult Index(string sortOrder, string searchString)
  2. {
  3. ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
  4. ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
  5. var students = from s in db.Students
  6. select s;
  7. if (!String.IsNullOrEmpty(searchString))
  8. {
  9. students = students.Where(s => s.LastName.Contains(searchString)
  10. || s.FirstMidName.Contains(searchString));
  11. }
  12. switch (sortOrder)
  13. {
  14. case "name_desc":
  15. students = students.OrderByDescending(s => s.LastName);
  16. break;
  17. case "Date":
  18. students = students.OrderBy(s => s.EnrollmentDate);
  19. break;
  20. case "date_desc":
  21. students = students.OrderByDescending(s => s.EnrollmentDate);
  22. break;
  23. default:
  24. students = students.OrderBy(s => s.LastName);
  25. break;
  26. }
  27.  
  28. return View(students.ToList());
  29. }

  在大多数情况下,我们调用同一个方法时,在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添加搜索框:

  1. <p>
  2. @Html.ActionLink("Create New", "Create")
  3. </p>
  4. @using (Html.BeginForm())
  5. {
  6. <p>
  7. Find by name: @Html.TextBox("SearchString")
  8. <input type="submit" value="Search" />
  9. </p>
  10. }

  效果图:

3.添加分页

3.1.安装PagedList.MVC:

  1. Install-Package PagedList.Mvc

3.2.修改Controllers\StudentController.cs

  1. using PagedList;
  1. public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
  2. {
  3. ViewBag.CurrentSort = sortOrder;
  4. ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
  5. ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
  6.   
  7. if (searchString != null)
  8. {
  9. page = ;
  10. }
  11. else
  12. {
  13. searchString = currentFilter;
  14. }
  15.  
  16. ViewBag.CurrentFilter = searchString;
  17.  
  18. var students = from s in db.Students
  19. select s;
  20. if (!String.IsNullOrEmpty(searchString))
  21. {
  22. students = students.Where(s => s.LastName.Contains(searchString)
  23. || s.FirstMidName.Contains(searchString));
  24. }
  25. switch (sortOrder)
  26. {
  27. case "name_desc":
  28. students = students.OrderByDescending(s => s.LastName);
  29. break;
  30. case "Date":
  31. students = students.OrderBy(s => s.EnrollmentDate);
  32. break;
  33. case "date_desc":
  34. students = students.OrderByDescending(s => s.EnrollmentDate);
  35. break;
  36. default: // Name ascending
  37. students = students.OrderBy(s => s.LastName);
  38. break;
  39. }
  40.  
  41. int pageSize = ;
  42. int pageNumber = (page ?? );
  43. return View(students.ToPagedList(pageNumber, pageSize));
  44. }

  当页面第一次加载或者用户没有点击分页或排序链接时,所有的参数都是空值。

  ViewBag.CurrentSort用于点击分页时保存排序信息。

  ViewBag.CurrentFilter用于保存搜索信息,并且当页面刷新时给搜索框赋值。当搜索条件改变时,page值重置为1。

3.3.修改Views\Student\Index.cshtml

  1. @model PagedList.IPagedList<ContosoUniversity.Models.Student>
  2. @using PagedList.Mvc;
  3. <link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
  4.  
  5. @{
  6. ViewBag.Title = "Students";
  7. }
  8.  
  9. <h2>Students</h2>
  10.  
  11. <p>
  12. @Html.ActionLink("Create New", "Create")
  13. </p>
  14. @using (Html.BeginForm("Index", "Student", FormMethod.Get))
  15. {
  16. <p>
  17. Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
  18. <input type="submit" value="Search" />
  19. </p>
  20. }
  21. <table class="table">
  22. <tr>
  23. <th>
  24. @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })
  25. </th>
  26. <th>
  27. First Name
  28. </th>
  29. <th>
  30. @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter=ViewBag.CurrentFilter })
  31. </th>
  32. <th></th>
  33. </tr>
  34.  
  35. @foreach (var item in Model) {
  36. <tr>
  37. <td>
  38. @Html.DisplayFor(modelItem => item.LastName)
  39. </td>
  40. <td>
  41. @Html.DisplayFor(modelItem => item.FirstMidName)
  42. </td>
  43. <td>
  44. @Html.DisplayFor(modelItem => item.EnrollmentDate)
  45. </td>
  46. <td>
  47. @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
  48. @Html.ActionLink("Details", "Details", new { id=item.ID }) |
  49. @Html.ActionLink("Delete", "Delete", new { id=item.ID })
  50. </td>
  51. </tr>
  52. }
  53.  
  54. </table>
  55. <br />
  56. Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
  57.  
  58. @Html.PagedListPager(Model, page => Url.Action("Index",
  59. 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

  1. public class EnrollmentDateGroup
  2. {
  3. [DataType(DataType.Date)]
  4. public DateTime? EnrollmentDate { get; set; }
  5.  
  6. public int StudentCount { get; set; }
  7. }

4.2.修改HomeController.cs

  1. private SchoolContext db = new SchoolContext();
  2. //...
  3. public ActionResult About()
  4. {
  5. IQueryable<EnrollmentDateGroup> data = from student in db.Students
  6. group student by student.EnrollmentDate into dateGroup
  7. select new EnrollmentDateGroup()
  8. {
  9. EnrollmentDate = dateGroup.Key,
  10. StudentCount = dateGroup.Count()
  11. };
  12. return View(data.ToList());
  13. }
  14. //...
  15. protected override void Dispose(bool disposing)
  16. {
  17. db.Dispose();
  18. base.Dispose(disposing);
  19. }

4.3.修改Views\Home\About.cshtml

  1. @model IEnumerable<ContosoUniversity.ViewModels.EnrollmentDateGroup>
  2.  
  3. @{
  4. ViewBag.Title = "Student Body Statistics";
  5. }
  6.  
  7. <h2>Student Body Statistics</h2>
  8.  
  9. <table>
  10. <tr>
  11. <th>
  12. Enrollment Date
  13. </th>
  14. <th>
  15. Students
  16. </th>
  17. </tr>
  18.  
  19. @foreach (var item in Model) {
  20. <tr>
  21. <td>
  22. @Html.DisplayFor(modelItem => item.EnrollmentDate)
  23. </td>
  24. <td>
  25. @item.StudentCount
  26. </td>
  27. </tr>
  28. }
  29. </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. 安装PHP出现make: *** [sapi/cli/php] Error 1 解决办法

    ext/iconv/.libs/iconv.o: In function `php_iconv_stream_filter_ctor':/home/king/php-5.2.13/ext/iconv/ ...

  2. 注册表-各种功能-隐藏IE、隐藏硬盘、禁用硬件

    1.在[我的电脑]上隐藏软驱 在[开始]→[运行]→输入[Regedit]→[HKEY_CURRENT_USER]→[Software] →[Microsoft] →[Windows]→[Curren ...

  3. 说一说window.parent

    <iframe>标签是很常用的,嵌在页面之中,可以做独立的加载和刷新.比如说,页面分左右或者上下结构,一般左侧和上侧是导航部分,右侧和下侧是目标页面的展示部分,只需要设置导航链接的targ ...

  4. iOS 使用fir、 蒲公英 进行内部测试

    fir 蒲公英需要去注册账号并认证,按提示即可完成. 测了公司账号.个人开发账号,2个都可以用,就是要在配置文件里加上测试者的udid. 步骤: 1.添加测试机的udid edit配置文件,添加刚刚加 ...

  5. JBPM学习(二):ProcessEngine与Service API

    1.获取processEngine的方法: a) 方法一 private ProcessEngine processEngine = new Configuration().setResource(& ...

  6. lettCode-Array

    1   Remove Element    lintcode-172 描述: 删相同元素,反现有长度 记忆:标不同元素,反标记值 public int removeElement(int[] a, i ...

  7. mysqldump 备份原理8

    /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; http://www.cnblogs.com/lyhabc/p/38 ...

  8. Qt之QtScript(一)

    C++和JavaScript相互通信.今天就学习QtScript模块吧. Qt 包含完全集成的 ECMA 标准脚本引擎.Qt Script 集成了 QObject,为脚本提供了 Qt 的信号与槽 (S ...

  9. Android自定义View之ProgressBar出场记

    关于自定义View,我们前面已经有三篇文章在介绍了,如果筒子们还没阅读,建议先看一下,分别是android自定义View之钟表诞生记.android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检 ...

  10. Linux下如何在打开终端的时候自动配置相关环境

    参考博客“Linux启动文件.设置环境变量的位置”(http://www.2cto.com/os/201305/208251.html) 在不可取的root权限的时候可以选择编辑~/.bashrc文件 ...