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. Also accepts method calls, reflection, typeof(...) .…