[转载]ASP.NET MVC 3 开发的20个秘诀(七)[20 Recipes for Programming MVC 3]:对列表进行排序

baacloud免费翻墙vpn注册使用

[转载][翻译]ASP.NET MVC 3 开发的20个秘诀(七)[20 Recipes for Programming MVC 3]:对列表进行排序 – O2DS – 博客园.

议题

现在有一个很大的列表(例如,图书列表),想找到某一项是非常难的。如果针对列表中的某一项进行排序,应该会对查找有所帮助。

解决方案

将书籍清单列表的列标题更新为链接,当链接被点击的时候,将通过Linq针对选中列的内容进行排序(通过再次点击标题链接来切换升序还是降序)。

讨论

与我之前使用过的框架相比添加排序、自动生成视图的过程让我感到有些惊讶。希望在外来的MVC版本中,他可以成为整体框架的一部分。参考 ASP.NET MVC的网站首页上示例,我们需要定义一个Switch语句,每一列排序情况都需要复制一个Case来实现。还好我们的这个案例当中只有五个项需要排序, 情况还不算太坏。如果以后需要针对比如作者或者其他列排序,只需要复制此Case来实现。在下面的示例中,我们将使用Dynamic Linq Library来简化工作。

Linq library 可以从数据库中查询并返回强类型结果。编程工具提供了如智能感知支持和编译时错误检测,我们很多的共奏都将基于这些功能进行操作。

在BooksController控制器和Books、Index视图中添加生成排序支持。以下是Index视图的代码:

@model IEnumerable<MvcApplication4.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标记,使用Html helper将静态文本转换为HTML链接。

接下来,需要修改BookController中的Index方法。此方法将会接受一个新的排序参数,此参数将在Linq执行查询时指定结果排序的列。更会在ViewBag创建一个新的变量存储每个列的排序条件。

Microsoft针对Linq提供了新的免费扩展DynamicQuery类,这个扩展允许在运行的时候动态生成查询语句,可以通过访问 http://msdn2.microsoft.com/en-us/vcsharp/bb894665.aspx 下载到C#版本。下载后解压到硬盘的某个位置,在目录中找到这个文件并添加到项目工程中“~\CSharpSamples\LinqSamples \DynamicQuery\DynamicQuery\Dynamic.cs”。为了更好的组织代码,我们需要在项目工程中创建“Utils”文件夹, 右键单击“Utils”文件夹选择“添加”->“现有项”,然后通过浏览窗口找到这个动态类(或者也可以直接通过拖拽将文件放入“Utils”目 录)。

动态类添加完成后,编辑更新BooksController:

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 MvcApplication4.Models;
using MvcApplication4.Resources;

namespace MvcApplication4.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());
        }
        ...
    }

}

参考

System.Linq.Expressions 名字空间 原书地址 书籍源代码

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏