PagedList使用LINQ Skip and Take,但使用Count of results显示分页

我试图显示一个过滤的产品列表,基于Categoryfilter和ItemsPerPage但我在尝试与PagedList一起使用时遇到了一些问题。

如果我需要编写自己的分页代码,或者有办法使用PagedList获得我需要的结果,那么具有PagedList专业知识的人可以建议我。

我正在使用LINQ的Skip&Take函数来仅获取当前页面上需要显示的行数,但我仍然希望根据filter的总计数来分页链接以显示页面。

例如:我的搜索filter找到50个结果,但由于我每页的行数是10个项目,我使用LINQ的Skip()和Take()只返回10行。 我仍然需要在我的View.cshtml中显示页面链接<< 1 | 2 | 3 | 4 | 5 >>现在使用默认的PagedList,我只得到<> ,我知道为什么我只看到一个页面,但我只想知道如何使其工作以显示正确数量的页面链接,而只获得一个子集结果

**我的目标是将优化的查询写入数据库,以便网页响应性能快速。

这是我的Action方法的代码。 代码获得了正确的结果,但分页不起作用,因为我需要它:

public ViewResult List(int page =1, string category =null) { if (category != null) this.CurrentCategory = category; var products = repository.Products .Where(p => this.CurrentCategory == null || p.Category == this.CurrentCategory) .OrderBy(p => p.ProductID) .Skip((page -1) * PageSize) .Take(PageSize); return View(products.ToList().ToPagedList(page, PageSize)); } 

以下是View中处理分页的代码段。 我查看了项目的Github网站,但找不到提供自定义页面的扩展方法。 我认为它只会根据’每页的项目数’和@Model中的产品的Count()来呈现页数:

 @model IPagedList //foreach loop that renders the @Model //Code that displays the pagination using PagedList 
@Html.PagedListPager(Model, page => Url.Action("List", new { page = page, category = ViewBag.CurrentCategory }), PagedListRenderOptions.OnlyShowFivePagesAtATime )

我有完全相同的问题,我最终使用StaticPagedList。 你可以做这样的事情

 public ViewResult List(int page =1, string category =null) { if (category != null) this.CurrentCategory = category; var products = repository.Products .Where(p => this.CurrentCategory == null || p.Category == this.CurrentCategory) .OrderBy(p => p.ProductID) .Skip((page -1) * PageSize) .Take(PageSize); var count = repository.Products .Where(p => this.CurrentCategory == null || p.Category == this.CurrentCategory).Count(); var resultAsPagedList = new StaticPagedList(products, page, PageSize, count); return View(resultAsPagedList); } 

至于视图,您只需要替换模型类型

 @model StaticPagedList 

ToPagedList内部使用TakeSkip ,当您使用IQueryable类的扩展时,这将导致您需要的数据库查询。 它还将TotalItemCount检索到其元数据中。

有时您可能需要将查询结果带入内存,因为您使用的方法无法转换为sql。 这意味着您必须将PagedList转换回Enumerable 。 您可以使用StaticPagedList方法解决此问题,如下所示:

  var superset= repository.Products .Where(p => this.CurrentCategory == null || p.Category == this.CurrentCategory) .OrderBy(p => p.ProductID) .ToPagedList(page, PageSize); var subset = superset .AsEnumerable() .Select(p => new ProductViewModel { OtherData = p.UntranslateableMethod() }) var model = new StaticPagedList(subset, superset.GetMetaData()); } 

从评论中的方法摘要:

初始化PagedList.StaticPagedList类的新实例,该实例包含已划分的子集以及有关超集大小和子集在其中的位置的信息。

您仍可能需要单独要求计数。

 var products = repository.Products .Where(p => this.CurrentCategory == null || p.Category == this.CurrentCategory); var numProds = products.Count(); var mypage = products.OrderBy(p => p.ProductID) .Skip((page -1) * PageSize) .Take(PageSize); 

如果使用PagedList的方法,则不需要也使用LINQ .skip().take() 。 如果你这样做,那么你是预先限制列表,使用库是没有意义的,因为你首先过滤列表以通过.skip().take()获取pagesize结果,然后将这些pagesize结果传递给再次过滤到pagesize ,当然会是相同的,但是然后PagedList不知道总数是多少。

如果要确保未加载所有结果,只需将IQueryable发送到PagedList而不是EnumerableList 。 PagedList将为您添加.Skip().Skip() ,您的数据库将只返回这些结果。

以上解释是正确的。 但是当你分配静态选择列表时..

 new StaticPagedList(products, page, PageSize, count);. 

它显示的实际计数页面链接数较少。 如果Count为10,如果您的页面大小为5,它只显示2页。

如果要显示所有页面链接可用的计数,那么

 pass count*5 ie count*pagesize new StaticPagedList(products, page, PageSize, count*5);//in my case page size is 5 

或新的StaticPagedList(产品,页面,PageSize,count * pagesize);

因此它提供页面中所有可用的计数。