The current builder infrastructure has an annoying flaw. The Select/SelectMany expressions can be applied only at the start of the query. This forces users to have an additional Query just for the select expressions. It doesn't feel natural and creates a lot of confusion.
We should refactor the infrastructure so the select expressions can be applied at the end of the query. That's more idiomatic, mimics LINQ better, and it's simply the correct way. Implementation-wise, this will require us to have two completely separate chains, one for ISpecificationBuilder<T> and another for ISpecificationBuilder<T, TResult>. This implies that we have to duplicate all extension methods. It's a bit tedious work and harder to maintain, but it's worth it.
Other than that, the select extensions should break the chain (they will return void), and no further chaining will be allowed on top of them. This more accurately describes our builders and avoids the assumption that any further expressions are applied to the projected result (which is not the case, we're not operating on IEnumerable/IQueryable).
Breaking Changes:
- The
Select/SelectMany are applied at the end of the chain or in a separate Query clause. These extension methods return void and no further chaining is possible.
- Folks who have custom extensions, should align to the new infrastructure and create extensions methods for both
ISpecificationBuilder<T> and ISpecificationBuilder<T, TResult>
The current builder infrastructure has an annoying flaw. The
Select/SelectManyexpressions can be applied only at the start of the query. This forces users to have an additionalQueryjust for the select expressions. It doesn't feel natural and creates a lot of confusion.We should refactor the infrastructure so the select expressions can be applied at the end of the query. That's more idiomatic, mimics LINQ better, and it's simply the correct way. Implementation-wise, this will require us to have two completely separate chains, one for
ISpecificationBuilder<T>and another forISpecificationBuilder<T, TResult>. This implies that we have to duplicate all extension methods. It's a bit tedious work and harder to maintain, but it's worth it.Other than that, the select extensions should break the chain (they will return void), and no further chaining will be allowed on top of them. This more accurately describes our builders and avoids the assumption that any further expressions are applied to the projected result (which is not the case, we're not operating on IEnumerable/IQueryable).
Breaking Changes:
Select/SelectManyare applied at the end of the chain or in a separateQueryclause. These extension methods return void and no further chaining is possible.ISpecificationBuilder<T>andISpecificationBuilder<T, TResult>