通过前面的教程学习, 你可以实现一个简单的书籍管理系统. 在本教程将向书籍索列表页面中添加排序功能.
下图显示你完成本教程后书籍列表页面的样子. 列标题是一个链接, 用户可以单击它使数据按该列排序. 反复单击列标题在升序排列和降序排列之间切换.
一, 向 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 中单步执行调试程序.
来源: https://www.cnblogs.com/chillsrc/p/9415425.html