Skip to content

Instantly share code, notes, and snippets.

@BenMakesGames
Last active January 1, 2024 02:01
Show Gist options
  • Save BenMakesGames/94b643593104dc341561e8f7f584ca7d to your computer and use it in GitHub Desktop.
Save BenMakesGames/94b643593104dc341561e8f7f584ca7d to your computer and use it in GitHub Desktop.
public sealed class PaginatedResults<T>
{
public required IReadOnlyList<T> Results { get; init; }
public required int Page { get; init; }
public required int PageSize { get; init; }
public required int TotalCount { get; init; }
public int TotalPages => (int)Math.Ceiling(TotalCount / (double)PageSize);
}
// this code assumes you want 1-indexed page numbers (instead of 0-indexed).
// if you prefer 0-indexed, remove the "- 1" and "+ 1"s below.
public static class IQueryableExtensionsForPaginatedResults
{
public static PaginatedResults<T> ToPaginatedResults<T>(this IQueryable<T> query, int pageNumber, int pageSize)
{
var totalNumberOfRecords = query.Count();
pageNumber = Math.Clamp(pageNumber - 1, 0, (int)Math.Ceiling(totalNumberOfRecords / (float)pageSize));
var results = query
.Skip(pageNumber * pageSize)
.Take(pageSize)
.ToList();
return new PaginatedResults<T>()
{
Results = results,
Page = pageNumber + 1,
PageSize = pageSize,
TotalCount = totalNumberOfRecords
};
}
public static async Task<PaginatedResults<T>> ToPaginatedResultsAsync<T>(this IQueryable<T> query, int pageNumber, int pageSize, CancellationToken cancellationToken)
{
var totalNumberOfRecords = await query.CountAsync(cancellationToken);
pageNumber = Math.Clamp(pageNumber - 1, 0, (int)Math.Ceiling(totalNumberOfRecords / (float)pageSize));
var results = await query
.Skip(pageNumber * pageSize)
.Take(pageSize)
.ToArrayAsync(cancellationToken);
return new PaginatedResults<T>()
{
Results = results,
Page = pageNumber + 1,
PageSize = pageSize,
TotalCount = totalNumberOfRecords
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment