学习ASP.NET Core Razor 编程系列十六——排序
学习ASP.NET Core Razor 编程系列目录
在本教程中,我们来学习如何进行排序。
通过前面的教程学习,你可以实现一个简单的书籍管理系统。 在本教程将向书籍索列表页面中添加排序功能。
下图显示你完成本教程后书籍列表页面的样子。 列标题是一个链接,用户可以单击它使数据按该列排序。 反复单击列标题在升序排列和降序排列之间切换。
一、向 OnGetAsync方法添加排序功能
为了在书籍列表页面中添加排序功能,你将更改书籍控制器中的OnGetAsync或OnGet方法并向书籍索引视图添加相关的代码。
1) 在Visual Studio 2017的解决方案资源管理器中找到 Books\ Index.cshtml.cs文件,添加排序字符串,代码如下:
public string NameSort { get; set; } public string DateSort { get; set; } public string CurrentFilter { get; set; } public string CurrentSort { get; set; }
2) 同时修改OnGetAsync(string author, string searchString)方法,添加排序字符串:
public async Task OnGetAsync(string author, string searchString,string sortOrder) { IQueryable<string> AuthorQuery = from m in _context.Book orderby m.Author select m.Author; var books = from m in _context.Book select m; if (!String.IsNullOrEmpty(searchString)) { books = books.Where(s => s.Name.Contains(searchString)); } if (!String.IsNullOrEmpty(author)) { books = books.Where(x => x.Author == author); } Authors = new SelectList(await AuthorQuery.Distinct().ToListAsync()); //排序 NameSort = String.IsNullOrEmpty(sortOrder) ? "name_desc" : ""; DateSort = sortOrder == "Date" ? "date_desc" : "Date"; switch (sortOrder) { case "name_desc": books = books.OrderByDescending(s => s.Name); break; case "Date": books = books.OrderBy(s => s.ReleaseDate); break; case "date_desc": books = books.OrderByDescending(s => s.ReleaseDate); break; default: books = books.OrderBy(s => s.Name); break; } Book = await books.AsNoTracking().ToListAsync(); }
按上面的代码从 URL 中的查询字符串中接收sortOrder参数。 ASP.NET Core 提供的查询字符串作为参数传递给的操作方法。 “Name”或”Date”,后面可以选择性跟用于指定降序顺序的下划线和”desc”构成参数字符串。 默认排序顺序为升序。
第一次请求索引页时,没有任何查询字符串。 书籍按名称升序显示也就是缺省值中的排序方式。 当用户单击列标题的超链接,将向OnGetAsync方法提供相应的sortOrder查询字符串。
Razor 页面使用 NameSort 和 DateSort 为列标题超链接配置相应的排序字符串值。
NameSort = String.IsNullOrEmpty(sortOrder) ? "name_desc" : ""; DateSort = sortOrder == "Date" ? "date_desc" : "Date";
这两个语句都使用了三目运算符。 第一个语句指如果sortOrder参数为 null 或为空则 NameSort 设置为”name_desc”; 否则,设置为一个空字符串。 这两个语句实现下表中的功能:
当前的排序顺序 |
Name 排序超链接 |
出版日期 排序超链接 |
Name 升序排列 |
descending |
ascending |
Name 降序排列 |
ascending |
ascending |
出版日期 升序排列 |
ascending |
descending |
出版日期 降序排列 |
ascending |
ascending |
该方法使用 LINQ 指定要作为排序依据的列。 代码在switch 语句之前创建了IQueryable变量然后在 switch 语句中对其进行修改,并在switch语句之后调用ToListAsync方法。 当你创建和修改IQueryable变量时数据库不会接收到任何查询。将 IQueryable 对象转换成集合后才能执行查询。 通过调用 IQueryable 等方法可将 ToListAsync 转换成集合。 因此,IQueryable 代码会生成单个查询,此查询直到出现以下语句才执行:
Book = await books.AsNoTracking().ToListAsync();
二、向书籍列表页面中的标题添加超链接
1) 在Visual Studio 2017中打开Books /Index.cshtml文件,用以下代码替换,添加列标题超链接。 高亮代码为已更改的行。
@page @model RazorMvcBooks.Pages.Books.IndexModel @{ ViewData["Title"] = "Index"; } <h2>Index</h2> <p> <a asp-page="Create">Create New</a> </p> <form> <p> <select asp-for="Publish" asp-items="Model.Publishs"> <option value="">All</option> </select> 书籍名称 <input type="text" name="SearchString"> <input type="submit" value="查询" /> </p> </form> <table class="table"> <thead> <tr> <th> <a asp-page="./Index" asp-route-sortOrder="@Model.NameSort"> @Html.DisplayNameFor(model => model.Book[0].Name) </a> </th> <th> <a asp-page="./Index" asp-route-sortOrder="@Model.DateSort"> @Html.DisplayNameFor(model => model.Book[0].ReleaseDate) </a> </th> <th> @Html.DisplayNameFor(model => model.Book[0].Author) </th> <th> @Html.DisplayNameFor(model => model.Book[0].Price) </th> <th> @Html.DisplayNameFor(model => model.Book[0].Publishing) </th> <th></th> </tr> </thead> <tbody> @foreach (var item in Model.Book) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.ReleaseDate) </td> <td> @Html.DisplayFor(modelItem => item.Author) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> @Html.DisplayFor(modelItem => item.Publishing) </td> <td> <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> | <a asp-page="./Details" asp-route-id="@item.ID">Details</a> | <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a> </td> </tr> } </tbody> </table>
对于上面的代码中的两行斜体代码的说明:
向 Name 和 ReleaseDate 列标题添加超链接。
使用 NameSort 和 DateSort 中的信息为超链接设置当前的排序顺序值。
2) 在Visual Studio 2017中按F5,运行书籍管理应用程序。
3) 在浏览器中浏览到书籍列表页面。
4) 在书籍列表页面单击“Name”2次。如下图中1与2。
5)在书籍列表页面单击“出版日期”2次。如下图中1与2。
三、了解此功能实现过程
如果你想要更好地了解此功能的实现过程,可以进行以下操作:
1)在Visual Studio 2017的 Books/Index.cshtml.cs 文件的 switch (sortOrder) 上设置断点。
2) 添加对 NameSort 和 DateSort 的监视。
3)在 Books/Index.cshtml 中的 @Html.DisplayNameFor(model => model.Book[0].Name) 上设置断点。
4) 然后在Visual Studio 2017中单步执行调试程序。
推荐阅读
-
学习ASP.NET Core Razor 编程系列十二——在页面中增加校验
-
学习ASP.NET Core Razor 编程系列八——并发处理
-
学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面
-
学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)
-
学习ASP.NET Core Razor 编程系列十九——分页
-
学习ASP.NET Core Razor 编程系列九——增加查询功能
-
学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面
-
学习ASP.NET Core Razor 编程系列七——修改列表页面
-
学习ASP.NET Core Razor 编程系列十六——排序
-
学习ASP.NET Core Razor 编程系列一