Getting Started
FlexQuery.NET is a lightweight and powerful .NET library that enables dynamic filtering, sorting, paging, and projection over IQueryable (EF Core or any LINQ provider).
Installation
Install the core package via NuGet:
bash
dotnet add package FlexQuery.NET --version 1.7.2If you are using Entity Framework Core, install the async helpers:
bash
dotnet add package FlexQuery.NET.EFCore --version 1.7.2Quick Start
FlexQuery.NET is designed to be drop-in ready. Below are the two primary ways to use it in your ASP.NET Core controllers.
1. Simple Usage (Direct Parsing)
Best for rapid prototyping or simple internal tools where raw query string parsing is sufficient.
csharp
using FlexQuery.NET;
using FlexQuery.NET.Parsers;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class CustomersController : ControllerBase
{
private readonly AppDbContext _context;
public CustomersController(AppDbContext context) => _context = context;
[HttpGet]
public async Task<IActionResult> Get()
{
// 1. Parse raw query string into internal options
var options = QueryOptionsParser.Parse(Request.Query);
// 2. Apply filtering, sorting, and paging
var customers = await _context.Customers
.ApplyValidatedQueryOptions(options)
.ToListAsync();
return Ok(customers);
}
}2. Advanced Usage (Recommended)
Using the QueryRequest DTO is highly recommended for production APIs. It provides clean OpenAPI/Swagger documentation and allows you to enforce server-side security rules easily.
csharp
using FlexQuery.NET;
using FlexQuery.NET.Models;
using FlexQuery.NET.Parsers;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class CustomersController : ControllerBase
{
private readonly AppDbContext _context;
public CustomersController(AppDbContext context) => _context = context;
[HttpGet]
public async Task<IActionResult> Get([FromQuery] QueryRequest request, CancellationToken ct)
{
// 1. Parse the safe DTO into the execution model
var options = QueryOptionsParser.Parse(request);
// 2. Configure server-side security rules
options.MaxFieldDepth = 3;
options.AllowedFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"Id", "Name", "Email", "Orders.*"
};
// 3. Manual Validation (REQUIRED before ToProjectedQueryResultAsync)
var validator = new QueryValidator();
var validation = validator.Validate<Customer>(options);
if (!validation.IsValid)
{
return BadRequest(validation.Errors);
}
// 4. Execution (full pipeline: filter + sort + paging + projection)
// Returns shaped objects with paging metadata
var results = await _context.Customers
.ToProjectedQueryResultAsync(options, ct);
return Ok(results);
}
}Try It Out
Once your controller is set up, you can start querying immediately:
- Filter:
?filter=name:contains:john - Sort:
?sort=createdAt:desc - Page:
?page=1&pageSize=10 - JQL:
?query=age > 20 AND status = "Active"
