E.g.
from s in (from s1 in Students from s2 in Students select s1).Distinct()
from x in Xs
select new {s, x}
In this case, the nested from part must be represented as a subquery, otherwise the semantics are changed.
In MethodCallExpressionNodeBase, add a template-method Apply implementation that looks like this:
public QueryModel Apply (QueryModel queryModel, ClauseGenerationContext clauseGenerationContext) { if (queryModel.SelectOrGroupClause.ResultModifications.Count > 0) queryModel = WrapCompletedQueryModel (queryModel); DoApply (queryModel, clauseGenerationContext); return queryModel; }
WrapCompletedQueryModel is virtual and creates a new QueryModel with the old queryModel in a subquery in the main from clause. It is overridden in ResultModificationExpressionNodeBase.
DoApply is abstract and contains what is currently in the nodes' apply methods.
After the query model has been wrapped, the last expression node (Source) must be mapped to the main from clause generated that holds the SubQueryExpression. After that, every Resolve of that last node must return a QuerySourceReferenceExpression pointing to that main from clause.
Example:
from x in Xs from y in (from z in x.Friends select z) select y
Refactor ConstantExpressionNode:
Refactor ExpressionTreeParser:
Including all "modification" variables, etc.
In many ways, GroupClause is more similar to a result operator than it is to a SelectClause:
Therefore, GroupClause should be changed to be a result operator. Then, every QueryModel would always have a a SelectClause that might be changed
by a GroupOperator:
from x in Xs group x.Y by x.Z
=>
from x in Xs select x => GroupBy (x.Y, x.Z)
This result operator, however, changes the element type of the returned enumerable.