A high-performance, provider-agnostic query engine for the .NET ecosystem.
Build dynamic, paginated, and hierarchically grouped queries with a fluent API — execute anywhere.
QueryForge is a modular query engine. It decouples the intent of a query from its execution, allowing you to define your query once and run it against multiple data sources through different providers.
| Package | Description | Status | NuGet |
|---|---|---|---|
| PepperX.QueryForge | The provider-agnostic foundation. Core models (Query), fluent builders, the validation engine, and a dependency-free in-memory execution engine. |
✅ Released | |
| PepperX.QueryForge.Dapper | Compiles query models into parameterized SQL and executes it with Dapper against SQL Server, PostgreSQL, MySQL/MariaDB, Oracle and SQLite. Nothing is deployed to your database. | ✅ Released | |
| PepperX.QueryForge.EFCore | Entity Framework Core provider. Translates query models into expression trees so EF Core generates the SQL — works on every database EF Core supports and honours your model. | ✅ Released | |
| PepperX.QueryForge.InMemory | In-memory provider for any IEnumerable<T> — cached data, composed API results, or as a test double for the database providers. Zero dependencies. |
✅ Released |
| Engine | Dapper provider | EF Core provider |
|---|---|---|
| Microsoft SQL Server | ✅ | ✅ |
| PostgreSQL | ✅ | ✅ |
| MySQL / MariaDB | ✅ | ✅ |
| Oracle | ✅ | ✅ |
| SQLite | ✅ | ✅ |
| Anything else with an EF Core provider | — | ✅ |
The EF Core column is ✅ throughout because EF Core generates the SQL; QueryForge only builds the expression tree.
Two shared suites run against every provider on every build: 90 tests taking each input apart
(Criteria, Paging, SelectColumns, SortColumns, GroupByColumns, flat and grouped) and 35
business scenarios posting whole requests — dashboards, drill-down grids, exports, search, and raw
client JSON — against a seeded order book.
Both the Dapper and EF Core providers run those suites against real database servers — SQLite,
PostgreSQL, MySQL, SQL Server and Oracle — not just asserted SQL text. That is what surfaced the differences
worth standardising: null ordering (engines disagree by default, and EF Core inherited the problem by
deferring ORDER BY to the database) and loosely-typed filter values ("30" against an integer
column, which strict engines reject outright). Both are handled, so the same request returns the same
answer wherever it runs. See tests/README.md.
QueryForge is built around a core set of engineering principles:
- 🛡️ Security by Default: Column names are checked against what the target actually exposes and
anything unrecognised is dropped, so a filter payload cannot be used to probe your schema. Values
are always parameters, never inlined text. On top of that, the validation engine (
SilentStriporThrowException) gives you explicit allow/deny lists and page-size clamps. - 🧩 Provider-Agnostic Core: Define your query intent once using the abstract
Querymodel, and execute it anywhere. A cross-provider parity suite asserts that the sameQueryreturns the sameQueryResult<T>from every provider. - 🔌 Nothing to Deploy: No stored procedures, no schema permissions, no startup migration step. Every provider builds its query at call time.
- 🔄 Automated CI/CD: All packages are built, tested, and published via GitHub Actions using OIDC Trusted Publishing.
This repository is an Umbrella Monorepo.
/src: Contains the source code for all QueryForge libraries. Each library folder contains its own dedicatedREADME.mdwith deep-dive technical documentation, C# examples, and API references./tests: ComprehensivexUnittest suites ensuring bulletproof reliability across all engines./samples: Runnable ASP.NET Core Minimal API projects demonstrating real-world integration.
Contributions, issues, and feature requests are welcome!
Unless otherwise specified, all packages in QueryForge are licensed under the MIT License — see the LICENSE file for details.
Engineered with ❤️ and C# by PepperX-Dev