【问题标题】:How to manually fill a PagedList, from the SUBSET of rows in the current page如何从当前页面中的行的 SUBSET 手动填充 PagedList
【发布时间】:2017-03-26 06:04:40
【问题描述】:

我自己手动计算了一堆行,包括一些我的数据库中没有的其他数据。为了提高效率,我只根据页码和页面大小计算当前页面中的行数。

我试图将其推入PagedList,但这需要整个数据集,而不仅仅是我想要显示的子集

请提供仅包含当前页面的自定义分页列表对象的完整示例。也许直接实现IPagedList??

另一个问题是,在计算整个列表之前,我可能无法知道总行数。这真的有必要吗?

【问题讨论】:

  • 这取决于IPagedList的实现。在我看来,PagedList 只是和其他模型一样的模型(或视图模型)。你可以通过设置它的属性来初始化它。
  • 分页列表也总是只包含您要显示的页面。它永远不会包含全部数据。
  • 最后我不得不计算总行数才能让它工作。

标签: c# asp.net .net asp.net-mvc pagination


【解决方案1】:

答案取决于IPagedList 的实现。 PagedList 只是一个模型(或视图模型),就像其他模型一样。您可以通过设置其属性来初始化它。分页列表也总是只包含您要显示的页面。它永远不会包含全部数据。

注意:此答案中的实现只是为了保持简单。要查看分页列表的流行实现,您可以查看X.PagedList。它包含一些自动和手动分页的实现以及一些对 ASP.NET MVC 有用的帮助器。

示例

假设我们有IPagedList这样的实现:

public interface IPagedList<T> : IList<T>
{
    int PageCount { get; set; }
    int PageSize { get; set; }
    int PageNumber { get; set; }
    int TotalItemsCount { get; set; }
}

public class PagedList<T> : List<T>, IPagedList<T>
    where T : class
{
    public int PageCount { get; set; }
    public int PageSize { get; set; }
    public int PageNumber { get; set; }
    public int TotalItemsCount { get; set; }
}

然后您可以像任何其他普通类一样通过分配其属性来实例化PagedList&lt;T&gt; 的实例。

您还可以创建一些扩展方法来帮助您提取IQueryable&lt;T&gt;IEnumerable&lt;T&gt; 的特定页面的数据:

using System;
using System.Collections.Generic;
using System.Linq;

public static class PagingExtensions
{
    public static PagedList<T> ToPagedList<T>(this IEnumerable<T> source, 
        int pageNumber, int pageSize) where T : class
    { return source.AsQueryable().ToPagedList(pageNumber, pageSize); }
    public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, 
        int pageNumber, int pageSize) where T : class
    { return CreatePagesList<T>(source, pageNumber, pageSize); }
    private static PagedList<T> CreatePagesList<T>(IQueryable<T> source, 
        int pageNumber, int pageSize) where T : class
    {
        var items = new List<T>();
        var pageIndex = pageNumber - 1;
        if (source == null) source = new List<T>().AsQueryable();
        var totalItemsCount = source.Count();
        if (pageNumber < 1)
            throw new ArgumentOutOfRangeException("pageNumber cannot be less than 1.");
        if (pageSize < 1)
            throw new ArgumentOutOfRangeException("pageSize cannot be less than 1.");
        var pageCount = 0;
        if (totalItemsCount > 0)
            pageCount = (int)Math.Ceiling(totalItemsCount / (double)pageSize);
        if (pageIndex >= pageCount)
            pageIndex = Math.Max(pageCount - 1, 0);
        if (pageIndex < pageCount && totalItemsCount > 0)
            items.AddRange(source.Skip((pageIndex) * pageSize).Take(pageSize).ToList());
        var pagedList=  new PagedList<T>()
        {
            PageNumber = pageNumber, PageSize = pageSize,
            PageCount = pageCount, TotalItemsCount = totalItemsCount
        };
        pagedList.AddRange(items);
        return pagedList;
    }
}

【讨论】:

  • 您的回答和@Kaspars Ozols 的回答都符合我的需要。我会和你一起去,因为你是第一个。
  • 感谢您的反馈:) 如本答案中的答案实现中所述,只是为了保持简单。要查看分页列表的流行实现,您可以查看X.PagedList
【解决方案2】:

对于这个任务,我建议使用现有的 NuGet 包,如下所示: https://www.nuget.org/packages/PagedList

在这个特定的库中,您可以生成要显示的元素子集,并从该列表中创建 StaticPagedList

这是一个示例:

public class UserController : Controller
{
    public object Index(int? page)
    {
        var pageIndex = (page ?? 1) - 1; //MembershipProvider expects a 0 for the first page
        var pageSize = 10;
        int totalUserCount; // will be set by call to GetAllUsers due to _out_ paramter :-|

        var users = Membership.GetAllUsers(pageIndex, pageSize, out totalUserCount);
        var usersAsIPagedList = new StaticPagedList<MembershipUser>(users, pageIndex + 1, pageSize, totalUserCount);

        ViewBag.OnePageOfUsers = usersAsIPagedList;
        return View();
    }
}

在此处查看源代码和其他示例:https://github.com/TroyGoode/PagedList

【讨论】:

  • 该库在X.PagedList 下维护,正如我在answer 中提到的那样。
  • @RezaAghaei,你是对的。感谢您指出这一点,我已经使用 TroyGoode 的 PagedList 有一段时间了,并且有一段时间没有访问过项目站点,因此有关它没有被维护的信息已经溜走了。
  • 您的回答和@RezaAghaei 的回答都符合我的要求。我只能投票给一个获胜的答案......我会和他一起去,因为他是第一个。
猜你喜欢
  • 1970-01-01
  • 2021-12-02
  • 2014-11-20
  • 1970-01-01
  • 2020-11-24
  • 1970-01-01
  • 2022-01-05
  • 2018-10-14
  • 1970-01-01
相关资源
最近更新 更多