QueryBuilder is a lightweight utility for dynamically composing LINQ queries in Entity Framework Core. It simplifies filtering, sorting, and pagination logic.
var query = new QueryBuilder(db.Users) .Where("Age", ">", 18) .OrderBy("LastName") .Skip(10) .Take(20) .Build() .ToList(); //Returns users over 18, sorted by last name, paginated
var filter = queryBuilder
.AddJoin(typeof(SalesOrder.SalesOrderDetail), "ProductID", "ProductID", "Inner")
.AddJoin(typeof(SalesOrder.SalesOrderHeader), "SalesOrderID", "SalesOrderID", "Inner")
.AndWhere("Name", "StartsWith", "Road")
.AndWhere("UnitPrice", ">", 2000M, typeof(SalesOrder.SalesOrderDetail))
.OrElse("OrderQty", ">", 20 , typeof(SalesOrder.SalesOrderDetail))
.AndWhere("SalesOrderDetailID", "IN", (115,156), typeof(SalesOrder.SalesOrderDetail))
.Build(_context.Products, _context).Cast() ;
` SELECT [p].[ProductID], [p].[ListPrice], [p].[Name], [s0].[SalesOrderDetailID], [s0].[OrderQty], [s0].[ProductID],
[s0].[SalesOrderID], [s0].[UnitPrice], [s1].[SalesOrderID], [s1].[OrderDate]
FROM [Production].[Product] AS [p]
INNER JOIN (
SELECT [s].[SalesOrderDetailID], [s].[OrderQty], [s].[ProductID], [s].[SalesOrderID], [s].[UnitPrice]
FROM [Sales].[SalesOrderDetail] AS [s]
WHERE ([s].[UnitPrice] > 2000.0 OR [s].[OrderQty] > 20) AND [s].[SalesOrderDetailID] IN (115, 156)
) AS [s0] ON [p].[ProductID] = [s0].[ProductID]
INNER JOIN [Sales].[SalesOrderHeader] AS [s1] ON [s0].[SalesOrderID] = [s1].[SalesOrderID]
WHERE [p].[Name] LIKE N'Road%'`
Modern APIs often require dynamic filtering, sorting, and pagination. QueryBuilder standardizes this logic, reducing boilerplate and improving consistency across endpoints.
- Provide a fluent API for dynamic query composition
- Support
Where,OR,Skip, andTakeout of the box - Support joins Inner,Left,Right,Full Outer
- Support Groupby, Aggregation, Order By
- Allow JSON-based query definitions for frontend integration(API Integration)
- Validation Layer
- Export query into a portable format(JSON/XML) for logging and Debugging
- SQL Injection safety, Query caching and Async support
- Keep the tool lightweight , dependency-free , and EF-Core friendly
-Supports multiple entity joins(Inner) with type safe LINQ expressions.
-Process the query in the Database instead of In-Memory
-Supports filter with "==",">=","<=",">","<","!=", "IN","NOT IN", "LIKE"
-Clear error handling for type mismatches in Property/parameter expressions.
-QueryBuilder is designed to work with frontend framewroks and traditional MVC view through a .NET API.
-Works with AngularJS, ReactJS, MVC Views, jQuery, or any client that can send JSON payloads.
-All query construction is handled server-side.
-clients never need to know EF Core navigation paths or database column names.
-Example Payload:
-User can specify the root entity dynamically in the JSON request.QueryBuilder will resolve the correct DbSet<T> internally.
-Filters on related entities automatically create the required joins.
-Clients do not need to specify JOIN conditions explicitly (Automated JOIN resolution).
-Pagination support
`{ "RootEntity": "Product",
"Filters":
[ { "Field": "ProductName", "Condition": "==", "Value": "Road-150 Red, 56" },
{ "Field": "OrderQuantity", "Condition": ">", "Value": 20 } ],
"Skip": 0,
"Take": 50 }`
- No client-side DB knowledge required
- Dynamic queries without writing raw SQL
- Safe and type-checked
- No support for complex joins or groupings , frontend integration , orderBy dynamic properties , advanced filters with nested properties in the initial release
This is a small , evolving project. If you'd like to contribute:
- Feel free to fork the repo and submit a pull request with clear description
- No formal release or branching rules yet - Please keep the 'master' branch stable
- If you are adding new features, consider updating the README with example
- For questions or ideas , feel free to open an issue.
- Use .NET 8.0/C# 12