(7)为结果排序

问题

你有一个很庞大的列表(例如,图书列表),你不能很容易找到你想找的东西。以列表中某一列为基础排序,可以帮助你更快的去找到你想要的东西。

解决方案

在book list的标题上添加一个链接。当用户点击链接的时候,使用Dynamic Linq Library去为结果排序,给予选择的列。(升序或者降序)。再点一次链接的话,就会反转顺序。      

讨论

和以前我用过的框架相比较,我对于在自动生成的View里添加一个排序有点惊讶。希望在未来版本的MVC中,脚手架可以帮我们去做这件事。另一件我需要做的事就是在ASP.NET MVC 的主页上提供一个或更多的选项可以去切换排序。在图书的例子里,只有5个列需要被排序,也不算太糟。但是如果这个功能应用到其他的例子上。可能是作者列等,工作量就要增加啦!在下边的例子,我们如果用Dynamic Linq Library就简单多啦!

默认的,linq 类库 允许强类型的表达式从数据库生成结果。这有一些优势,比如,全方位的智能感知,编译时错误消息。当然,就像我上边说的,Build那些有用的功能也变成了很大的工作量。

为了支持排序,在BooksController 和Books index view 需要做以下更改:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
@model IEnumerable< MvcApplication.Models.Book >
< h2 >@ViewBag.Title</ h2 >
< p >
     @Html.ActionLink((string)ViewBag.CreateLink, "Create")
</ p >
< table >
     < tr >
         < th >
             @Html.ActionLink((string)ViewBag.TitleDisplay,
"Index", new { sortOrder = ViewBag.TitleSortParam })
         </ th >
         < th >
             @Html.ActionLink((string)ViewBag.IsbnDisplay,
"Index", new { sortOrder = ViewBag.IsbnSortParam })
         </ th >
         < th >
             @ViewBag.SummaryDisplay
         </ th >
         < th >
             @Html.ActionLink((string)ViewBag.AuthorDisplay,
"Index", new { sortOrder = ViewBag.AuthorSortParam })
         </ th >
         < th >
             @ViewBag.ThumbnailDisplay
         </ th >
         < th >
             @Html.ActionLink((string)ViewBag.PriceDisplay,
"Index", new { sortOrder = ViewBag.PriceSortParam })
         </ th >
         < th >
             @Html.ActionLink((string)ViewBag.PublishedDisplay,
"Index", new
{
     sortOrder =
         ViewBag.PublishedSortParam
})
         </ th >
         < th >
         </ th >
     </ tr >
     @foreach (var item in Model)
     {
         < tr >
             < td >
                 @Html.DisplayFor(modelItem => item.Title)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Isbn)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Summary)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Author)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Thumbnail)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Price)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Published)
             </ td >
             < td >
                 @Html.ActionLink((string)ViewBag.EditLink,
"Edit", new { id = item.ID }) |
                 @Html.ActionLink((string)ViewBag.DetailsLink,
"Details", new { id = item.ID }) |
                 @Html.ActionLink((string)ViewBag.DeleteLink,
"Delete", new { id = item.ID })
             </ td >
         </ tr >
     }
</ table >
 

 

在上边的例子中,前边创建的<th>标签已不再是静态的文本。已经使用ActionLink替换成了HTML Helper中的HTML link。

接下来BookController的 Index action也需要被更新。这个action将要接收一个新的参数: sortOrder。接下来我们要使用LINQ 根据这列为结果排序。微软已经提供了一个免费的 动态查询类,它是linq下的扩展,允许你根据表达式动态的查询。命名空间为using System.Linq.Dynamic。下载这个类的C#版本可以访问:http://msdn2.microsoft.com/en-us/vcsharp/bb894665.aspx.(译者:记得点下边的 I accept啊!)下载完,你需要解压缩。动态linq查询类可以在这里被找到: ~CSharpSamplesLinqSamplesDynamic

QueryDynamicQueryDynamic.cs. 这个文件一定要加到项目里。为了合理组织项目结构。我建议你把他加到Utils目录下。右击Utils目录->添加->已经存在的项,并找到dynamic linq

class (或者你直接把那个文件夹拖拽到Utils目录下)。

添加完成后,按照如下代码更新BooksController:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Web;
using System.Web.Mvc;
using MvcApplication.Models;
using MvcApplication.Resources;
namespace MvcApplication.Controllers
{
     public class BooksController : Controller
     {
         private BookDBContext db = new BookDBContext();
         //
         // GET: /Books/
         public ViewResult Index(string sortOrder)
         {
             #region ViewBag Resources
 
             #endregion
             #region ViewBag Sort Params
             // Define the sort orders - if the same link is
             // clicked twice, reverse the direction from
             // ascending to descending
             ViewBag.TitleSortParam = (sortOrder == "Title")
             ? "Title desc" : "Title";
             ViewBag.IsbnSortParam = (sortOrder == "Isbn")
             ? "Isbn desc" : "Isbn";
             ViewBag.AuthorSortParam = (sortOrder == "Author")
             ? "Author desc" : "Author";
             ViewBag.PriceSortParam = (sortOrder == "Price")
             ? "Price desc" : "Price";
             ViewBag.PublishedSortParam =
             (String.IsNullOrEmpty(sortOrder))
             ? "Published desc" : "";
             // Default the sort order
             if (String.IsNullOrEmpty(sortOrder))
             {
                 sortOrder = "Published desc";
             }
             #endregion
             var books = db.Books.OrderBy(sortOrder);
             return View(books.ToList());
         }
 
     }
}
 

上边的例子允许根据传入的sortOrder 变量排序。上面的代码是轻微的不安全,是为了证明 以最小的影响执行动态LINQ查询的过程。由于这个变量可以通过URL传入,为input数据添加一些验证是十分重要的,这样可以确保用户没法进行恶意行为。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lin&Yi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值