C# 使用LINQ Skip和Take的分页列表,但使用结果计数显示分页

C# 使用LINQ Skip和Take的分页列表,但使用结果计数显示分页,c#,linq,asp.net-mvc-4,pagination,pagedlist,C#,Linq,Asp.net Mvc 4,Pagination,Pagedlist,我试图根据类别过滤器和ItemsPerPage显示产品的筛选列表,但在尝试将其与PagedList一起使用时遇到了一些问题 如果我需要编写自己的分页代码,或者有没有办法使用PagedList获得所需的结果,具有PagedList专业知识的人可以建议我 我使用LINQ的Skip&Take函数只获取当前页面上需要显示的行数,但是我仍然希望分页链接根据过滤器的总计数显示页面 例如:我的搜索过滤器会找到50个结果,但由于我每页的行数是10个项目,因此我使用LINQ的Skip()&Take()只返回10行

我试图根据类别过滤器和ItemsPerPage显示产品的筛选列表,但在尝试将其与PagedList一起使用时遇到了一些问题

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

我使用LINQ的Skip&Take函数只获取当前页面上需要显示的行数,但是我仍然希望分页链接根据过滤器的总计数显示页面

例如:我的搜索过滤器会找到50个结果,但由于我每页的行数是10个项目,因此我使用LINQ的Skip()&Take()只返回10行。我仍然需要在my View.cshtml中显示页面链接 现在使用默认的页面列表,我只能看到,我知道为什么我只能看到一个页面,但我只是想知道如何才能在只获得结果子集的情况下显示正确数量的页面链接

**我的目标是将优化后的查询写入数据库,这样网页响应性能会更快

下面是我的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));
}
下面是视图中处理分页的代码片段。我查看了该项目的Github站点,但找不到提供自定义页面的扩展方法。我认为它只会根据@Model:

@model IPagedList<Product>

//foreach loop that renders the @Model

//Code that displays the pagination using PagedList
<div style="text-align:center">
    @Html.PagedListPager(Model, page => Url.Action("List", new { page = page, category =  ViewBag.CurrentCategory }), PagedListRenderOptions.OnlyShowFivePagesAtATime
    )
</div>
@model IPagedList
//呈现@Model的foreach循环
//使用PagedList显示分页的代码
@Html.PagedListPager(Model,page=>Url.Action(“List”,new{page=page,category=ViewBag.CurrentCategory}),pagedListRenderations.OnlyShowFivePagesAtime
)

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

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,而不是
Enumerable
List
。PagedList将为您添加
.Skip()
.Take()
,您的数据库将只返回这些结果。

我遇到了完全相同的问题,最后使用了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<Product>(products, page, PageSize, count);

    return View(resultAsPagedList);
}
公共视图结果列表(int page=1,string category=null) { 如果(category!=null)this.CurrentCategory=category; var products=repository.products .Where(p=>this.CurrentCategory==null | | p.Category==this.CurrentCategory) .OrderBy(p=>p.ProductID) .Skip((第1页)*页面大小) 。取(页面大小); var count=repository.Products 其中(p=>this.CurrentCategory==null | | p.Category==this.CurrentCategory).Count(); var resultAsPagedList=新的静态页面列表(产品、页面、页面大小、计数); 返回视图(结果页面列表); } 至于视图,您只需要替换模型类型

@model StaticPagedList<Product>
@model StaticPagedList

上述解释是正确的。 但当您分配静态选择列表时

new StaticPagedList<Product>(products, page, PageSize, count);.
新建静态页面列表(产品、页面、页面大小、计数);。
它显示的页面链接数量比实际数量少。 如果计数为10,则如果页面大小为5,则仅显示2页

如果要以计数方式显示所有可用页面链接, 然后

pass count*5 ie count*pagesize
新的静态页面列表(产品、页面、页面大小、计数*5)//在我的情况下,页面大小是5
或新的静态页面列表(产品、页面、页面大小、计数*页面大小)


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

ToPagedList
在内部使用
Take
Skip
,当您使用
IQueryable
类的扩展时,将生成所需的数据库查询。它还将
TotalItemCount
检索到其元数据中

有时,您可能需要将查询结果放入内存,因为您使用的方法无法转换为sql。这意味着您必须将
页面列表
转换回可枚举的
。您可以使用如下方法解决此问题:

   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<ProductViewModel>(subset,
       superset.GetMetaData());
}
var superset=repository.Products
.Where(p=>this.CurrentCategory==null
||p.类别==此.CurrentCategory)
.OrderBy(p=>p.ProductID)
.ToPagedList(页面,页面大小);
变量子集=超集
.可计算的()
.选择(p=>new ProductViewModel
{
OtherData=p.不可翻译的方法()
})
var模型=新的静态页面列表(子集,
superset.GetMetaData());
}
从注释中的方法摘要可以看出:

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


谢谢你的回复。我的问题是如何自定义PagedList框架以显示自定义分页方案。我知道如何筛选搜索并获得结果。Count()。但是到目前为止,我所有将Count()插入到页面列表的尝试都失败了。在开始编写自己的自定义分页之前,我想看看是否可以使用PagedList实现自定义,因为它是一个很好的分页框架W
   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<ProductViewModel>(subset,
       superset.GetMetaData());
}