I Got Tired of Hand-Rolling Expression Trees. So I Built QuerySpec.
Two years ago I shipped an endpoint that took a JSON filter from the client and ran it against EF Core. Every CRUD app eventually grows one. The product team called it "advanced search". I called it the part of the codebase I was scared to touch.
The first version interpolated SQL. We caught that in code review. The second used System.Linq.Dynamic.Core and parsed the input as a C# expression — beautiful, until I realised I'd handed the world the keys to the database. The third was 600 lines of hand-written Expression.Lambda calls with a switch statement that grew every sprint.
That endpoint is the reason QuerySpec exists.
The four ways devs solve this, three of them bad
1. String interpolation into raw SQL. I have personally code-reviewed $"WHERE {col} = '{val}'" in three different codebases. It's always there because someone said "we'll fix it later".
2. System.Linq.Dynamic.Core . Cute.…