65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 简单的搜索类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (9投票s)

2012年1月5日

CPOL

2分钟阅读

viewsIcon

50150

downloadIcon

1745

在 ASP.NET 中实现简单可定制的搜索。

Sample Image

引言

本文介绍了一些简单的代码,可以轻松添加搜索功能,用于搜索任何对象(文件、.NET 类)并将搜索结果一起显示在一个视图中。

背景

此演示在 ASP.NET MVC 中呈现,因此基本的 MVC 知识会很有帮助,尽管此解决方案可以应用于其他 .NET 环境。

Using the Code

主要工作是在抽象基类 Searcher 的实现中完成的。在此示例中,在构造函数中创建了一些虚拟数据,然后在 Search 方法中查询匹配项,并将其投影到 SearchResult 中。请注意 RouteInformation 的填充方式。RouteInformation 字典中的条目将用于在 MVC 视图中创建 ActionLink

public class ProductSearcher : Searcher
{
    private List<Product> Products { get; set; }

    public ProductSearcher()
    {
        //Dummy up some data here...
        Products = new List<Product>();
    }

    public override IEnumerable<SearchResult> Search(string searchTerm)
    {
        var result = Products.Where(p => p.Description.ToLower().Contains(
                     searchTerm.ToLower()) || 
                     p.Name.ToLower().Contains(searchTerm.ToLower()))
            .Select(p => new SearchResult
            {
                Category = "Product",
                Description = p.Name,
                Id = p.ProductId,
                OriginatingObject = p
            }).ToList();

        result.ForEach(p => p.RouteInformation = GetRouteInfo(p.Id));

        return result;
    }

    private static Dictionary<string, string> GetRouteInfo(int id)
    {
        return new Dictionary<string, string>
                                {
                                    {"controller", "product"},
                                    {"action", "details"},
                                    {"Id", id.ToString()}
                                };
    }
}

SearchCore 使用 Searcher 实现的 List 初始化,它应该使用这些实现来构建搜索结果。当调用 Search 时,它只是遍历它们,调用它们的 Search 方法并汇总结果。

public class SearchCore
{
    private List<Searcher> Searchers { get; set; }

    public SearchCore(List<Searcher> searchers)
    {
        Searchers = searchers;
    }

    public IEnumerable<SearchResult> Search(string searchTerm)
    {
        var result = new List<SearchResult>();

        foreach (Searcher searcher in Searchers)
        {
            result.AddRange(searcher.Search(searchTerm));
        }
        return result;
    }
}

搜索控制器

搜索控制器只有一个 ActionResult,它创建我们的 Searcher 实例并将它们添加到列表中,然后将该列表传递给 SearchCore。它使用秒表来测量执行搜索所花费的时间。可以启用 Search 方法上的缓存以提高性能。

private SearchCore SearchCore { get; set; }

public SearchController()
{
    var searchers = new List<Searcher> {new ProductSearcher(), new CompanySearcher()};

    SearchCore = new SearchCore(searchers);
}

//Uncomment below to enable caching.
//[OutputCache(VaryByParam = "searchTerm", Duration = 180)]
[HttpPost]
public ActionResult Search(string searchTerm)
{
    var model = new SearchResponse();

    //Use a stopwatch to measure the time it takes to perform the search.
    var s = new System.Diagnostics.Stopwatch();
    s.Start();
    model.Results = SearchCore.Search(searchTerm);
    s.Stop();
    model.OriginalSearchTerm = searchTerm;
    model.TimeTaken = s.Elapsed;
    return View(model);
}

搜索视图

搜索视图只是打印原始搜索词和所花费的时间,并遍历结果,打印链接(使用 RouteInfoLink 扩展方法),然后调用原始对象的 DisplayTemplate(无论是什么)。Display Templates 存储在 Search 文件夹的 DisplayTemplates 子文件夹中。

@model SimpleSearch.SearchResponse
<html>
<head>
    <title>Search Results</title>
</head>
<body>
    <h2>Search Results</h2>
    @Html.Raw(string.Format("Your search for <strong>{0}</strong> returned {1} 
        results in {2} seconds", Model.OriginalSearchTerm, Model.Results.Count(), 
        Math.Round(Model.TimeTaken.TotalSeconds, 3)))<br />
    @*Only meaningful if caching is enabled on the controller*@
    <em>@String.Format("Cached at {0}", DateTime.Now.ToShortTimeString())</em>
    @foreach (var item in Model.Results)
    {
        <section style="border: 0px none; display: block; float: none; padding: 0px">
            <h3>@item.Category - @Html.RouteInfoLink(item.Description, item.RouteInformation)</h3>
            @Html.DisplayFor(m =>

显示模板

DisplayTemplate 只是以其强类型类型命名的标准 Razor 片段。

@model Search.Models.Product

<section style="border: 0px none; display:block; float:none; padding: 0px">
    @Model.Name<br />
    <b>Short Name: </b>@Model.ShortName<br/>
    @Model.Description<br/>
    <h3>£@Model.Price</h3>

</section>

关注点

这只是一个非常基本的实现,但它展示了如何使用相对较少的代码来完成真正有用的事情。

© . All rights reserved.