[转载]【译】MVC3 20个秘方-(10)根据关键字搜索 – 技术弟弟 – 博客园.
当排序和分页和过滤都不够帮用户去找到他们想要的结果时,想一个最好的备选方式是让用户输入(关键字)他们想要什么。
解决方案
用HtmlHelper创建一个新的From和 文本输入框,并且借助LINQ根据用户输入的关键字在之前过滤过的结果里查找。
讨论
和前边的秘方很像,添加一个根据keyword 搜索的功能需要更新 Book/Index view 和 BookController。在View里添加一个新的from和textbox 让用户输入keyword。同时也要确保当用户改变排序规则、过滤、分页时,关键字保持。
下边的代码是对View的更新:
@model PagedList.IPagedList<MvcApplication.Models.Book> <h2>@MvcApplication4.Resources.Resource1.BookIndexTitle</h2> <p> @Html.ActionLink("Create New", "Create") </p> <p> Show: @if (ViewBag.CurrentFilter != "") { @Html.ActionLink("All", "Index", new { sortOrder = ViewBag.CurrentSortOrder, Keyword = ViewBag.CurrentKeyword }) } else { @:All } | @if (ViewBag.CurrentFilter != "NewReleases") { @Html.ActionLink("New Releases", "Index", new { filter = "NewReleases", sortOrder = ViewBag.CurrentSortOrder, Keyword = ViewBag.CurrentKeyword }) } else { @:New Releases } | @if (ViewBag.CurrentFilter != "ComingSoon") { @Html.ActionLink("Coming Soon", "Index", new { filter = "ComingSoon", sortOrder = ViewBag.CurrentSortOrder, Keyword = ViewBag.CurrentKeyword }) } else { @:Coming Soon } </p> @using (Html.BeginForm()) { @:Search: @Html.TextBox("Keyword")<input type="submit" value="Search" /> } @Html.Partial("_Paging") <table> <tr> <th> @Html.ActionLink("Title", "Index", new { sortOrder = ViewBag.TitleSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) </th> <th> @Html.ActionLink("Isbn", "Index", new { sortOrder = ViewBag.IsbnSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) </th> <th> Summary </th> <th> @Html.ActionLink("Author", "Index", new { sortOrder = ViewBag.AuthorSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) </th> <th> Thumbnail </th> <th> @Html.ActionLink("Price", "Index", new { sortOrder = ViewBag.PriceSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) </th> <th> @Html.ActionLink("Published", "Index", new { sortOrder = ViewBag.PublishedSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) </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("Edit","Edit", new { id = item.ID }) | @Html.ActionLink("Details","Details", new { id = item.ID }) | @Html.ActionLink("Delete","Delete", new { id = item.ID }) </td> </tr> } </table> @Html.Partial("_Paging")
最终,BookController 需要被更新,在下边的例子,Index() action 更新
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.Utils; using PagedList; namespace MvcApplication.Controllers { public class BooksController : Controller { private BookDBContext db = new BookDBContext(); // // GET: /Books/ public ViewResult Index(string sortOrder, string filter,string Keyword, int page = 1) { #region ViewBag Resources #endregion #region ViewBag Sort Params #endregion var books = from b in db.Books select b; #region Keyword Search if (!String.IsNullOrEmpty(Keyword)) { books = books.Where(b => b.Title.ToUpper().Contains(Keyword.ToUpper()) || b.Author.ToUpper().Contains( Keyword.ToUpper())); } ViewBag.CurrentKeyword = String.IsNullOrEmpty(Keyword) ? "" : Keyword; #endregion #region Filter Switch #endregion int maxRecords = 1; int currentPage = page - 1; return View(books.ToPagedList(currentPage, maxRecords)); } } }
译者:上边代码是以书名和作者名为搜索条件的。你也可以自己扩展。比如根据ISBN:
books = books.Where(b => b.Title.ToUpper().Contains(Keyword.ToUpper()) || b.Author.ToUpper().Contains( Keyword.ToUpper()||b.ISBN.ToUpper().Contains( Keyword.ToUpper()));
当然这样做的话查询效率会有问题。我们可以在UI提供一个dropdownlist 让用户去选择根据什么条件去搜索关键字。