PagedList using LINQ Skip and Take, but show paging using Count of results

前端 未结 5 1281
眼角桃花
眼角桃花 2020-12-15 06:02

I am trying to display a filtered list of of products, based on Category filter and ItemsPerPage but I\'m having some issues when trying to use it with PagedList.

So

相关标签:
5条回答
  • 2020-12-15 06:19

    I had the exactly same problem and I ended up using StaticPagedList. You can do something like this

    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);
    }
    

    as for the view, you just need to replace the model type

    @model StaticPagedList<Product>
    
    0 讨论(0)
  • 2020-12-15 06:19

    If you use PagedList's methods, you do not need to also use LINQ .skip() and .take(). If you do, then you are pre-limiting the list, and it would be pointless to use the library because you are first filtering down the list to get pagesize results by .skip() and .take() then passing those pagesize results to be filtered again down to pagesize, which will of course be the same, but then PagedList doesn't know what the total is.

    If you want to ensure you are not loading all results, simply send an IQueryable to PagedList instead of an Enumerable or List. PagedList will add the .Skip() and .Take() for you, and your database will only return those results.

    0 讨论(0)
  • 2020-12-15 06:24

    ToPagedList uses Take and Skip internally and when you use the extension to the IQueryable<T> class, that will result in the database query you require. It also retrieves the TotalItemCount into its Metadata.

    Sometimes you may need to bring the query results into memory because you are using a method that cannot be translated into sql. That means you have to convert the PagedList back to an Enumerable. You can get around this problem by using the StaticPagedList method like this:

       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());
    }
    

    From the summary of the method in comments:

    Initializes a new instance of the PagedList.StaticPagedList class that contains the already divided subset and information about the size of the superset and the subset's position within it.

    0 讨论(0)
  • 2020-12-15 06:25

    You will still likely have to ask for a count separately.

    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);
    
    0 讨论(0)
  • 2020-12-15 06:32

    The above explanation is correct. But when you are assigning Static select list..

    new StaticPagedList<Product>(products, page, PageSize, count);.
    

    It displays less number of page link from actual count. If Count is 10 it show only 2 pages if your page size is 5..

    If you want to show all pages link availabe in count, then

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

    or new StaticPagedList(products, page, PageSize, count*pagesize);

    thus it provide all available counts in pages.

    0 讨论(0)
提交回复
热议问题