예제 #1
0
        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)));
        }