Introduction
As applications grow in complexity and scale, managing large datasets becomes crucial for both performance and user experience. Pagination and filtering are essential techniques to efficiently handle and display large amounts of data. This article will guide you through implementing pagination and filtering in an ASP.NET Core 8.0 API using Entity Framework Core (EF Core).
Setting Up the Project
1. Create a New ASP.NET Core Project
create a new ASP.NET Core Web API project.
dotnet new webapi -n PaginationFilteringDemo
cd PaginationFilteringDemo
2. Add Entity Framework Core
Install the necessary EF Core packages.
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
3. Configure the Database Context
Create a Models folder and add an Item class.
namespace PaginationFilteringDemo.Models
{
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
}
Create an ApplicationDbContext class in the Data folder.
using Microsoft.EntityFrameworkCore;
using PaginationFilteringDemo.Models;
namespace PaginationFilteringDemo.Data
{
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Item> Items { get; set; }
}
}
Update appsettings.json with the connection string.
"ConnectionStrings": {
"DefaultConnection": "your connection string"
}
Configure the database context in Program.cs.
using Microsoft.EntityFrameworkCore;
using PaginationFilteringDemo.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Let's start implementing pagination
1. Create a Pagination Model
Create a PaginationParams class to define pagination parameters.
namespace PaginationFilteringDemo.Models
{
public class PaginationParams
{
private const int MaxPageSize = 50;
public int PageNumber { get; set; } = 1;
private int _pageSize = 10;
public int PageSize
{
get => _pageSize;
set => _pageSize = (value > MaxPageSize) ? MaxPageSize : value;
}
}
}
2. Add a Paged Response Class
Create a PagedResponse class to structure the paginated response.
using System.Collections.Generic;
namespace PaginationFilteringDemo.Models
{
public class PagedResponse<T>
{
public List<T> Data { get; set; }
public int PageNumber { get; set; }
public int PageSize { get; set; }
public int TotalRecords { get; set; }
public PagedResponse(List<T> data, int pageNumber, int pageSize, int totalRecords)
{
Data = data;
PageNumber = pageNumber;
PageSize = pageSize;
TotalRecords = totalRecords;
}
}
}
3. Modify the Controller
Create a controller and name the ItemController.
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PaginationFilteringDemo.Data;
using PaginationFilteringDemo.Models;
namespace PaginationFilteringDemo.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ItemsController : ControllerBase
{
private readonly ApplicationDbContext _context;
public ItemsController(ApplicationDbContext context)
{
_context = context;
}
[HttpGet]
public async Task<ActionResult<PagedResponse<Item>>> GetItems([FromQuery] PaginationParams paginationParams)
{
var query = _context.Items.AsQueryable();
var totalRecords = await query.CountAsync();
var items = await query.Skip((paginationParams.PageNumber - 1) * paginationParams.PageSize)
.Take(paginationParams.PageSize)
.ToListAsync();
var pagedResponse = new PagedResponse<Item>(items, paginationParams.PageNumber, paginationParams.PageSize, totalRecords);
return Ok(pagedResponse);
}
}
}
Filtering
1. Add Filtering Parameters
Extend the PaginationParams class to include filtering parameters.
namespace PaginationFilteringDemo.Models
{
public class PaginationParams
{
private const int MaxPageSize = 50;
public int PageNumber { get; set; } = 1;
private int _pageSize = 10;
public int PageSize
{
get => _pageSize;
set => _pageSize = (value > MaxPageSize) ? MaxPageSize : value;
}
public string SearchTerm { get; set; }
public string Category { get; set; }
}
}
2. Update the Controller for Filtering
[HttpGet]
public async Task<ActionResult<PagedResponse<Item>>> GetItems([FromQuery] PaginationParams paginationParams)
{
var query = _context.Items.AsQueryable();
if (!string.IsNullOrEmpty(paginationParams.SearchTerm))
{
query = query.Where(i => i.Name.Contains(paginationParams.SearchTerm));
}
if (!string.IsNullOrEmpty(paginationParams.Category))
{
query = query.Where(i => i.Category == paginationParams.Category);
}
var totalRecords = await query.CountAsync();
var items = await query.Skip((paginationParams.PageNumber - 1) * paginationParams.PageSize)
.Take(paginationParams.PageSize)
.ToListAsync();
var pagedResponse = new PagedResponse<Item>(items, paginationParams.PageNumber, paginationParams.PageSize, totalRecords);
return Ok(pagedResponse);
}
Conclusion
Implementing pagination and filtering in an ASP.NET Core 8.0 API using EF Core ensures that your application can handle large datasets efficiently. By following this guide, you can create a robust API that delivers data in a manageable and user-friendly manner.
Happy Coding!