private static Expression ProcessSubquery(ISessionFactory sessionFactory, ICollection <ExpressionHolder> elementExpression, QueryModel queryModel, Expression @group, QueryModel subQueryModel) { var resultTypeOverride = subQueryModel.ResultTypeOverride; if (resultTypeOverride != null && !resultTypeOverride.IsArray && !IsEnumerableOfT(resultTypeOverride)) { return(null); } SubQueryFromClauseFlattener.ReWrite(subQueryModel); var subQueryMainFromClause = subQueryModel.MainFromClause; var restrictions = subQueryModel.BodyClauses .OfType <WhereClause>() .Select(w => new NhWithClause(w.Predicate)); var join = new NhJoinClause(subQueryMainFromClause.ItemName, subQueryMainFromClause.ItemType, subQueryMainFromClause.FromExpression, restrictions); queryModel.BodyClauses.Add(@join); var visitor = new SwapQuerySourceVisitor(subQueryMainFromClause, @join); queryModel.TransformExpressions(visitor.Swap); var selector = subQueryModel.SelectClause.Selector; var collectionType = subQueryModel.GetResultType(); var elementType = selector.Type; var source = new QuerySourceReferenceExpression(@join); return(BuildSubCollectionQuery(sessionFactory, elementExpression, @group, source, selector, elementType, collectionType)); }
public static ExpressionToHqlTranslationResults GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, bool root, NhLinqExpressionReturnType?rootReturnType) { // Expand conditionals in subquery FROM clauses into multiple subqueries if (root) { // This expander works recursively SubQueryConditionalExpander.ReWrite(queryModel); } NestedSelectRewriter.ReWrite(queryModel, parameters.SessionFactory); // Remove unnecessary body operators RemoveUnnecessaryBodyOperators.ReWrite(queryModel); // Merge aggregating result operators (distinct, count, sum etc) into the select clause MergeAggregatingResultsRewriter.ReWrite(queryModel); // Swap out non-aggregating group-bys NonAggregatingGroupByRewriter.ReWrite(queryModel); // Rewrite aggregate group-by statements AggregatingGroupByRewriter.ReWrite(queryModel); // Rewrite aggregating group-joins AggregatingGroupJoinRewriter.ReWrite(queryModel); // Rewrite non-aggregating group-joins NonAggregatingGroupJoinRewriter.ReWrite(queryModel); SubQueryFromClauseFlattener.ReWrite(queryModel); // Rewrite left-joins LeftJoinRewriter.ReWrite(queryModel); // Rewrite paging PagingRewriter.ReWrite(queryModel); // Flatten pointless subqueries QueryReferenceExpressionFlattener.ReWrite(queryModel); // Flatten array index access to query references ArrayIndexExpressionFlattener.ReWrite(queryModel); // Add joins for references AddJoinsReWriter.ReWrite(queryModel, parameters); // Expand coalesced and conditional joins to their logical equivalents ConditionalQueryReferenceExpander.ReWrite(queryModel); // Move OrderBy clauses to end MoveOrderByToEndRewriter.ReWrite(queryModel); // Give a rewriter provided by the session factory a chance to // rewrite the query. var rewriterFactory = parameters.SessionFactory.Settings.QueryModelRewriterFactory; if (rewriterFactory != null) { var customVisitor = rewriterFactory.CreateVisitor(parameters); if (customVisitor != null) { customVisitor.VisitQueryModel(queryModel); } } // rewrite any operators that should be applied on the outer query // by flattening out the sub-queries that they are located in var result = ResultOperatorRewriter.Rewrite(queryModel); // Identify and name query sources QuerySourceIdentifier.Visit(parameters.QuerySourceNamer, queryModel); var visitor = new QueryModelVisitor(parameters, root, queryModel, rootReturnType) { RewrittenOperatorResult = result, }; visitor.Visit(); return(visitor._hqlTree.GetTranslation()); }