private static void FlattenSubQuery(QueryModel queryModel, QueryModel subQueryModel, GroupResultOperator groupBy) { foreach (var resultOperator in queryModel.ResultOperators.Where(resultOperator => !AcceptableOuterResultOperators.Contains(resultOperator.GetType()))) { throw new NotImplementedException("Cannot use group by with the " + resultOperator.GetType().Name + " result operator."); } // Move the result operator up. SubQueryFromClauseFlattener.InsertResultOperators(subQueryModel.ResultOperators, queryModel); for (var i = 0; i < queryModel.BodyClauses.Count; i++) { var clause = queryModel.BodyClauses[i]; clause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryModel)); //all outer where clauses actually are having clauses var whereClause = clause as WhereClause; if (whereClause != null) { queryModel.BodyClauses.RemoveAt(i); queryModel.BodyClauses.Insert(i, new NhHavingClause(whereClause.Predicate)); } } foreach (var bodyClause in subQueryModel.BodyClauses) { queryModel.BodyClauses.Add(bodyClause); } // Replace the outer select clause... queryModel.SelectClause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryModel)); // Point all query source references to the outer from clause var visitor = new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryModel.MainFromClause); queryModel.TransformExpressions(visitor.Swap); // Replace the outer query source queryModel.MainFromClause = subQueryModel.MainFromClause; }
public static Expression ReWrite(Expression expression, GroupResultOperator groupBy, QueryModel model) { var visitor = new GroupBySelectClauseRewriter(groupBy, model); return(TransparentIdentifierRemovingExpressionVisitor.ReplaceTransparentIdentifiers(visitor.Visit(expression))); }