As you can see from my last update on re-linq, we’ve now finished our planned refactoring for re-linq’s frontend, i.e. its main parsing infrastructure. Sure, that’s not a guarantee that there are no rough edges left, features missing, or bugs present (I’d rather not give that guarantee). But it means that the plan I gave in the middle of June has now been implemented.
For those of you who don’t remember, let me recap:
- We’ve implemented a completely new structural parsing approach for LINQ queries. (See IExpressionNode, QueryParser, ExpressionTreeParser.)
- We’ve implemented a powerful resolution mechanism which transforms select projections, where conditions, and similar expressions so that they point back to the query sources where their data actually stems from. (See IExpressionNode.Resolve and QuerySourceReferenceExpression.)
- We’ve cleaned up a lot and moved the SQL-specific parts (which, by the way, have not yet been refactored because they are not so useful for general-purpose LINQ providers) out of the way. We’ve rewritten eager fetching support and made it opt-in.
- We’ve changed our QueryModel and the clause classes into something truly transformable. You can simply take a Where clause from the left of a join and insert it to the right, if you want to. Or you can take subqueries in from clauses and flatten them out (at least if that’s semantically possible).
- We’ve implemented support for the Join and GroupJoin query methods.
- We’ve implemented support for the GroupBy query methods.
We believe that now re-linq truly is a great LINQ provider foundation that aids significantly in writing LINQ providers for any query system. And I’m talking about feature-rich, maintainable, and extensible LINQ providers, not the “let’s cast it to MethodInfo and check whether the method name is ‘Where’” ones. (If you believe that’s not so hard anyway, read Frans Bouma’s list of difficulties in creating a LINQ provider. Or just try to implement one that supports more than the most simple chains of Select and Where calls.)
This is not going to be the end of our extending re-linq, of course. I’ve lots of good ideas for further additions, for example:
- a simplifying transformation for identifying SQL-compatible calls to GroupBy,
- a simplifying transformation for identifying GroupJoins whose group items are used in a SelectMany clause, maybe modified with DefaultIfEmpty,
- an equality comparer for expression trees,
- a caching infrastructure,
- support for parsing of instance query methods,
- support for the GroupBy overload with a ResultSelector,
- and so on.
However, those ideas aren’t our top-most priorities at the moment. And this is an open-source project, after all. So if you have a good idea: send us a patch!