FlexQuery.NET
Every dynamic API eventually reimplements the same query engine: optional filters that compose, sortable columns, paging metadata, field selection, related-data loading — each one hand-built, each one a potential injection surface. FlexQuery.NET is that engine, done once: it transforms query parameters sent by clients into secure, server-side expression trees that translate to SQL.
Why FlexQuery.NET
- No OData dependency — powerful querying without OData's complexity, setup, and tight coupling.
- 100% server-side — all operations translate to SQL via expression trees. Nothing is fetched and filtered in memory; there is zero client evaluation.
- Security first — declare allowed and blocked fields per endpoint; every request is validated against your model and governance rules before any query runs.
- Multi-format — the native DSL, FQL (SQL-inspired), and MiniOData syntaxes on the same endpoint, all parsing to one internal model.
- Multiple providers — Entity Framework Core, Dapper, or any
IQueryablesource. - Observable — pipeline events, timing reports, and SQL previews built in.
How it works
- A client sends query parameters (
filter,sort,page,select, …) or a JSON request model. - FlexQuery parses them into a
QueryOptionsmodel using the selected query syntax. - Validation checks every field and operator against your entity model and governance rules — rejected requests never reach the database.
- The provider (EF Core or Dapper) applies the options as expressions or generated SQL.
- A
QueryResult<T>returns data plus paging metadata, aggregates, and cursor tokens.
The full pipeline is described in Execution Pipeline.
Package ecosystem
| Package | Purpose |
|---|---|
FlexQuery.NET | Core query engine — parsing, filtering, sorting, paging, projection, validation |
FlexQuery.NET.EntityFrameworkCore | Async execution, includes, and typed DTO queries for EF Core |
FlexQuery.NET.Dapper | SQL generation and execution for Dapper |
FlexQuery.NET.AspNetCore | ASP.NET Core integration with [FieldAccess] security attributes |
FlexQuery.NET.Diagnostics | Execution diagnostics, timing, and observability |
FlexQuery.NET.OpenApi | OpenAPI/Swagger documentation for FlexQuery endpoints |
FlexQuery.NET.Adapters.AgGrid | AG Grid Server-Side Row Model request/response adapter |
FlexQuery.NET.Adapters.Kendo | Kendo UI DataSource request adapter |
FlexQuery.NET.Parsers.Fql | FQL (FlexQuery Language) syntax parser |
FlexQuery.NET.Parsers.MiniOData | Lightweight OData-compatible syntax parser |
All packages target .NET 6, .NET 8, and .NET 10 (FlexQuery.NET.OpenApi targets .NET 9
and .NET 10).
The shape of an endpoint
Everything below is a complete ASP.NET Core controller — this is genuinely all it takes:
using FlexQuery.NET;
using FlexQuery.NET.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
[ApiController]
[Route("api/customers")]
public sealed class CustomersController(AppDbContext db) : ControllerBase
{
[HttpGet]
public async Task<IActionResult> Get(
[FromQuery] FlexQueryParameters parameters,
CancellationToken cancellationToken)
{
var result = await db.Customers
.AsNoTracking()
.FlexQueryAsync(parameters, cancellationToken: cancellationToken);
return Ok(result);
}
}From there, capability grows by configuration — governance sets, expand, aggregates, keyset paging — not by writing new endpoint code.
Where to next
- Installation — add the packages to your project.
- First Query — build a working endpoint in minutes.
- Configuration — global defaults and per-request overrides.
- Query Syntax — the three supported query languages.
- Security & Governance — locking endpoints down.