Details

Paged Result

How to implement a generic paginated result service in C#

Create a PagedResult DTO

public class PagedResult<T>
{
   public List<T> Items { get; set; }
   public int TotalCount { get; set; }
   public int PageSize { get; set; }
   public int CurrentPage { get; set; }
   public int TotalPages => (int)Math.Ceiling((double)TotalCount / PageSize);
   public PagedResult()
   {
       Items = [];
   }
}

Create the IPagedResultService Interface

public interface IPagedResultService
{
   Task<PagedResult<T>> GetPagedResultAsync<T>(
       IQueryable<T> query,
       int pageNumber,
       int pageSize)
       where T : class;
}

Implement the PagedResultService

public class PagedResultService : IPagedResultService
{
   public async Task<PagedResult<T>> GetPagedResultAsync<T>(
       IQueryable<T> query,
       int pageNumber,
       int pageSize)
       where T : class
    {
       var result = new PagedResult<T>
       {
           CurrentPage = pageNumber,
           PageSize = pageSize,
           TotalCount = await query.CountAsync(),
           Items = await query
           .Skip((pageNumber - 1) * pageSize)
           .Take(pageSize)
           .ToListAsync()
       };
       return result;
   }
}

Register the PagedResultService in Program.cs

services.AddScoped<IPagedResultService, PagedResultService>();

You can (and probably should) set a default value for pageNumber and pageSize at the highest level, eg at the controller level.