Как реализовать пагинацию в API в C# ASP.NET Core

Пагинация — это механизм разбиения данных на страницы, который помогает уменьшить нагрузку на сервер и улучшить пользовательский опыт. Начнем с создания модели запроса для пагинации:

public class PaginationParams
{
    public int PageNumber { get; set; } = 1;
    public int PageSize { get; set; } = 10;
}

Модель содержит параметры PageNumber и PageSize с значениями по умолчанию.

Расширение IQueryable для пагинации

Для удобства создадим расширение, которое будет применять пагинацию к IQueryable:

public static class IQueryableExtensions
{
    public static IQueryable<T> Paginate<T>(this IQueryable<T> query, PaginationParams paginationParams)
    {
        return query.Skip((paginationParams.PageNumber - 1) * paginationParams.PageSize)
                    .Take(paginationParams.PageSize);
    }
}

Этот метод использует Skip и Take для выборки данных нужной страницы.

Создание модели ответа

Дополнительно можно создать модель, содержащую данные и информацию о страницах:

public class PagedResponse<T>
{
    public IEnumerable<T> Data { get; set; }
    public int PageNumber { get; set; }
    public int PageSize { get; set; }
    public int TotalRecords { get; set; }
    public int TotalPages => (int)Math.Ceiling((double)TotalRecords / PageSize);

    public PagedResponse(IEnumerable<T> data, int pageNumber, int pageSize, int totalRecords)
    {
        Data = data;
        PageNumber = pageNumber;
        PageSize = pageSize;
        TotalRecords = totalRecords;
    }
}

Применение пагинации в контроллере

Пример использования пагинации в API-контроллере:

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly ApplicationDbContext _context;

    public ProductsController(ApplicationDbContext context)
    {
        _context = context;
    }

    [HttpGet]
    public async Task<ActionResult<PagedResponse<Product>>> GetProducts([FromQuery] PaginationParams paginationParams)
    {
        var query = _context.Products.AsQueryable();
        int totalRecords = await query.CountAsync();
        var data = await query.Paginate(paginationParams).ToListAsync();

        return Ok(new PagedResponse<Product>(data, paginationParams.PageNumber, paginationParams.PageSize, totalRecords));
    }
}

Реализация пагинации в ASP.NET Core включает в себя создание параметров запроса, расширения для IQueryable, модели ответа и использование их в контроллере API. Это улучшает производительность и делает API более удобным для работы с большими объемами данных.