C#语言中的分页转换

目录

介绍

背景

使用代码

代码示例


介绍

设计分页似乎是一项微不足道的任务。它只是选择一个页面大小(或一组页面大小)并坚持下去。不使用外部数据源时,这可以完美地工作。但是,当使用不同API的返回数据列表时,您可能会遇到与您的不同的分页设计不匹配。您可以采用不同来源的页面大小,但这对您的用户来说是不透明的。因此,您现在可以保留我们自己的设计并使用PaginationConversion助手,允许您轻松地将使用分页设计的页面请求转换为所请求数据源的分页。

背景

下面的示例说明了页面大小为5发件人)和页面大小为3收件人)的两种分页设计之间的页面重叠:

该表应如下所示:

对外观设计51页的请求需要第1页和外观设计32页的前两项。

对外观设计52页的请求需要外观设计32页、第3页和第4页第一项。

等。

使用代码

PaginationConversion类帮助我们轻松地从分页设计切换到任何其他设计。它使用Convert工厂方法,要求将设计的当前页面和页面大小转换为并将设计的页面大小转换为。

using System;

/// <summary>
/// Result for the conversion from one pagination design to another.
/// </summary>
public sealed class PaginationConversion
{
    #region Properties
    
    /// <summary>
    /// First page to request in the to design.
    /// </summary>
    public int FirstPage { get; }

    /// <summary>
    /// Page size of the to design.
    /// </summary>
    public int PageSize { get; }

    /// <summary>
    /// Number of pages required from the to design to fulfill the page size of the from design.
    /// </summary>
    public int PageCount { get; }
    
    /// <summary>
    /// Number of first items to skip from the first page of the to design.
    /// </summary>    
    public int NumberOfFirstItemsToSkip { get; }
    
    #endregion //***** Properties
    
    #region Constructors
    
    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="firstPage">First page to request in the to design</param>
    /// <param name="pageSize">Page size of the to design</param>
    /// <param name="pageCount">Number of pages required from the to design to fulfill the page size of the from design</param>
    /// <param name="numberOfFirstItemsToSkip">Number of first items to skip from the first page of the to design</param>
    private PaginationConversion(int firstPage, int pageSize, int pageCount, int numberOfFirstItemsToSkip)
    {
        FirstPage = firstPage;
        PageSize = pageSize;
        PageCount = pageCount;
        NumberOfFirstItemsToSkip = numberOfFirstItemsToSkip;
    }
    
    #endregion //***** Constructors
        
    #region Methods
    
    /// <summary>
    /// Converts a request for the current page of the from pagination design to the request(s) required for the to pagination design.
    /// </summary>
    /// <param name="fromCurrentPage">Current page in the from paginition design</param>
    /// <param name="fromPageSize">Page size in the from pagination design</param>
    /// <param name="toPageSize">Page size in the to pagination design</param>
    /// <returns>Settings required for the to pagination design</returns>
    public static PaginationConversion Convert(int fromCurrentPage, int fromPageSize, int toPageSize)
    {
        //***** Calculate the (one-based) index of the first item in the from design;
        double fromFirstItemIndex = (fromCurrentPage - 1) * fromPageSize + 1;

        //***** Calculate the first page in the to design to require items from;
        var toFirstPage = (int)Math.Floor((fromFirstItemIndex - 1) / toPageSize) + 1;

        //***** Calculate the (one-based) index of the first item in the to design;
        var toFirstItemIndex = (toFirstPage - 1) * toPageSize + 1;

        //***** Calculate the first items to skip in the first page of the to design;
        var toFirstPageFirstItemsToSkip = (int) fromFirstItemIndex - toFirstItemIndex;

        //***** Calculate the required page count for the to design;
        var toPageCount = (int) Math.Ceiling((fromPageSize - (toPageSize - toFirstPageFirstItemsToSkip)) / toPageSize) + 1;

        //***** Return result;
        return new PaginationConversion(
            toFirstPage,
            toPageSize,
            toPageCount,
            toFirstPageFirstItemsToSkip);
    }    
    
    #endregion //***** Methods
}

以下伪代码演示如何实现转换结果:

public sealed class DummyRepository
{
    /// <summary>
    /// Maximum page size in the to design.
    /// </summary>
    private const toPageSize = 36;  

    /// <summary>
    /// Get the items from the to system for the current page and page size of the from design.
    /// </summary>
    /// <param name="currentPage">Current page of the from design</param>
    /// <param name="pageSize">Page size of the from design</param>
    /// <returns>Items from the to system for the current page and page size of the from design</returns>
    public List<SomeEntity> Get(int currentPage, int pageSize)
    {
        //***** Convert from design into to design;
        var pagination = PaginationConversion.Convert(sourceCurrentPage: 5, sourcePageSize: 100, targetPageSize: 36);

        //***** List of results from to system;
        var result = new List<SomeEntity>();
        var index = 0;
        while (index < pagination.PageCount)
        {
            var page = someEntityRepository.Get(pagination.FirstPage + index, pagination.PageSize);
            result.AddRange(page);             
            index++;
        }

        //***** Check if first items need to be skipped. If so, remove first items from result;
        if (pagination.NumberOfFirstItemsToSkip > 0) result.RemoveRange(0, pagination.NumberOfFirstItemsToSkip);

        //***** Check if items in result exceed page size. If so, remove last items from result;
        if (result.Count > pageSize) result.RemoveRange(result.Count - (result.Count - pageSize), result.Count - pageSize);

        //*****
        return result;
    }
}

while循环迭代页数中的页数,并收集结果列表中的项目。从源收集项目后,将删除要跳过的第一个项目(如果有)和最后一个项目(如果已超出起始设计页面大小),从而生成发件人页面。

代码示例

下面的代码示例使用页面大小为3收件人系统生成虚拟数据源。发件人系统使用的页面大小为5

public class Program
{
    public static void Main(string[] args)
    {
        //***** Helper method for retrieving pages from an enumerable;
        static List<string> GetPage(IEnumerable<string> source, int currentPage, int pageSize) => source.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();

        //***** Pagination designs;
        const int fromCurrentPage = 2;
        const int fromPageSize = 5;
        const int toPageSize = 3;

        //***** Dummy data source ("to" system);
        var dataSource = new List<string>();
        for (var i=0; i < 20; i++)
            dataSource.Add($"Item {i+1}");
        
        //***** Pagination conversion;
        var pagination = PaginationConversion.Convert(fromCurrentPage, fromPageSize, toPageSize);

        //***** Iterate;
        var pages = new List<List<string>>();
        var result = new List<string>();
        var index = 0;
        while (index < pagination.PageCount)
        {
            var page = GetPage(dataSource, pagination.FirstPage + index, pagination.PageSize);
            pages.Add(page);
            result.AddRange(page);
            index++;
        }

        //***** Check if first items need to be skipped. If so, remove first items from result;
        if (pagination.NumberOfFirstItemsToSkip > 0) result.RemoveRange(0, pagination.NumberOfFirstItemsToSkip);

        //***** Check if items in result exceed page size. If so, remove last items from result;
        if (result.Count > fromPageSize) result.RemoveRange(result.Count - (result.Count - fromPageSize), result.Count - fromPageSize);
    }
}

下面的屏幕截图显示了请求的结果:

我希望这对你有意义,就像对我一样。无论如何写它很有趣:D

https://www.codeproject.com/Tips/5334616/Pagination-conversion-in-Csharp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值