![]() |
Search and Filter using ASP.NET Core Web API and EF Core |
What is Filtering and Searching?
- Filtering - In the context of Web API, Filtering is the mechanism of retrieving a subset of results from the datasource where each record meets a specific condition. This means that only the rows that satisfy the user-provided criteria will be returned.
- Searching - Search is the process of retriving results which matches the search criteria either fully or partially. Typically, we search for a keyword and return the set of results that match that keyword.
Implement Search And Filtering in ASP.NET Core Web API
Create a Filter model
We’ll start by creating a model class for filtering. This model will contain all the fields that we want to filter by. In this case, we want to filter employee records based on Designation, Date of Birth (DOB), and Department. Additionally, we’ll implement a search function to look up employees by their Name. Below is the filter model that includes all the fields used for filtering and searching:
public class FilterModel
{
public string? SearchByName { get; set; }
public string? Designation { get; set; }
public DateTime? DobStatrtDate { get; set; }
public DateTime? DobEndDate { get; set; }
public string? Department { get; set; }
}
Update Controller Action method to accept Filter Parameters
// GET: api/<EmployeesController>
[HttpGet]
public async Task<IActionResult> Get([FromQuery] FilterModel filter, int pageIndex = 1, int pageSize = 10)
{
var results = await _employeeService.GetAllEmployees(pageIndex, pageSize, filter);
return Ok(results);
}
[FromQuery] will bind the query parameters to FilterModel, if the field matches with the query params passed in the url.
We’ve added the FilterModel
as a query parameter, but the filtering logic will reside in the EmployeeService
class, where the GetAllEmployees
method is implemented. Therefore, we need to pass the FilterModel
from the action method to the service method so that records are filtered.
Update Interface method declaration
IEmployeeService
interface to accept the FilterModel
:Task<PaginatedListModel<EmployeeModel>> GetAllEmployees(int pageIndex, int pageSize, FilterModel filter);
Update the GetAllEmployee() method
GetAllEmployees
method to accept the filter model and apply the filtering logic based on the conditions provided. Here’s the updated method:public async Task<PaginatedListModel<EmployeeModel>> GetAllEmployees(int pageIndex, int pageSize, FilterModel filters)
{
var employees = employeeDBContext.Employees.AsQueryable();
if (!string.IsNullOrWhiteSpace(filter.Designation))
employees = employees.Where(employee => employee.Designation == filter.Designation);
if (!string.IsNullOrWhiteSpace(filter.Department))
employees = employees.Where(employee => employee.Department == filter.Department);
if (filters.DobStartDate.HasValue)
employees = employees.Where(employee => employee.DOB >= filter.DobStartDate);
if (filters.DobEndDate.HasValue)
employees = employees.Where(employee => employee.DOB <= filter.DobEndDate);
var totalRecords = await employees.CountAsync();
var employeesList = await employees.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
return new PaginatedListModel<EmployeeModel>(employeesList, totalRecords, pageIndex, pageSize);
}
Understanding the filter logic
var employees = employeeDBContext.Employees.AsQueryable();
This line is crucial for enabling dynamic filter. Here AsQueryable() method is important. This method will allow the Employees Collection as Queryable object. Which means it will not immediately retrive the rows from Employees Table from database. Rather it will only build the query till all the filter condition are applied and it will retrive the rows from DB only when ToListAsync() or CountAsync() is applied to that object.
With the above line, it will retrive all the employees from DB as currently it doesn't has any filter condition.
Apply Filters to the Queryable Object
if (!string.IsNullOrWhiteSpace(filter.Designation))
employees = employees.Where(employee=> employee.Designation == filter.Designation);
Here we've added the filter condition to our employee Queryable Object. This will add the condition to the employees object to filter the rows which matches the Designation passed.
Same logic is applied for the rest of all the conditions. We're not going through all the filter fields.
Final Execution
var totalRecords = await employees.CountAsync();
var employeesList = await employees.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
The first line will return the count of total records which statisfies the filtercondtion. And the second line will return the rows which satisfies the given filter condition. Here the DB call will happen as we've used CountAsync() and ToListAsync(). This is when entity framework will send the query to get the desired result.
And in the last line we're returning the results retrived.
Testing Search and Filter Functionality Using Swagger UI
GET /api/Employees request view
![]() |
Swagger View having Search and Filter Options for the Employees |
![]() |
Search and Filter API Response |
Comments
Post a Comment