【问题标题】:PagedList Search suffering from inefficiencyPagedList Search 效率低下
【发布时间】:2014-11-14 10:24:10
【问题描述】:

我正在尝试在超过 10,000 条记录上实现搜索功能。这在使用 PagedList 时会遇到速度问题。

public ActionResult CrmBlogGroupType(int? page, bool? Name, bool? AuthorTitle, bool?    Description, string search, int? PageSize, string type)
{
    try
    {
    if (type==null)
    {
        type = "A";
    }
    IEnumerable<Usp_getBlogSetPosts_Result> _objBlogSet = _dataLayer.GetBlogSet(type);
    //The above _objBlogSet has around 10 thousand records

    ViewBag.CurrentPage = page;

    ViewBag.Name = Name ==null?false:Name;
    ViewBag.AuthorTitle = AuthorTitle == null ? false : AuthorTitle;
    ViewBag.Description = Description == null ? false : Description;

    ViewBag.Search = search;
    ViewBag.type = type;

    if (Name == true && AuthorTitle == false && Description == false)
    {
        _objBlogSet = _objBlogSet.Where(p => p.author_name.ToLower().Contains(search.ToLower())).ToPagedList(page ?? 1, PageSize ?? 10);
    } 

    return View(_objBlogSet);

    catch (Exception ex)
    {
        throw ex;
    }
}

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 pagedlist


    【解决方案1】:

    我假设您使用的是 Troy Goode 的分页列表 (https://github.com/TroyGoode/PagedList)

    尝试使用 IQueryable,而不是使用 IEnumerable。 这样,分页在服务器端完成,性能会更好。

    【讨论】:

    • 公开列表 Get_MVP_Consultants() { List obj_Consultants = _dbContext.Tbl_MVPConsultant.Where(p => p.Visibility == true).ToList();返回 obj_Consultants;以上是我获取数据的 Datalayer 方法。如何将该代码修改为 IQueryable ..
    • 不要转换该执行列表。一旦你这样做,数据库就会被击中并返回所有内容。
    • 嗨@lusocoding 我听从了你的建议并更改了我的Datalayer方法以返回IQueryable Result..但是ToPagedList()方法不允许Iqueryable Result..现在如何继续..
    • 你为什么说它不允许 IQueryable?你得到什么样的错误?
    • 嗨@lusocoding,这是数据层代码:IQueryable _objConsultants =_datalayer.Get_MVP_Consultants();这是我得到错误的地方, _objConsultants = _objConsultants.Where(p => p.Name.ToLower().Contains(SearchTextbox.ToLower())).ToPagedList(pagenumber ?? 1, PageSize ?? 5);错误是无法将类型“System.Collections.Generic.List”隐式转换为“System.Linq.IQueryable”。存在显式转换(您是否缺少演员表?)
    【解决方案2】:

    这一切都取决于_dataLayer.GetBlogSet() 中发生的事情。您当前的代码很可能会拉入整个表并过滤内存中的数据。

    该方法应返回IQueryable&lt;Usp_getBlogSetPosts_Result&gt;,因此该集合上的ToPagedList() 内部Skip()Take() 将被转换为SQL 查询。

    【讨论】:

    • 能否请您修改我的代码以便我理解。