public void SetUp() { _detailSource = ExpressionHelper.CreateQueryable <Kitchen>(); _sectorSource = ExpressionHelper.CreateQueryable <Restaurant>(); var query = from s1 in ExpressionHelper.CreateQueryable <Cook>() from sd in (from sector in _sectorSource where sector.ID > 10 select sector.SubKitchen) from s2 in s1.Assistants where sd.Name == "Maths" select new NonTransformedTuple <Cook, Kitchen> (s1, sd); _queryModel = ExpressionHelper.ParseQuery(query); _mainFromClause = _queryModel.MainFromClause; _additionalFromClause1 = (AdditionalFromClause)_queryModel.BodyClauses[0]; _additionalFromClause2 = (AdditionalFromClause)_queryModel.BodyClauses[1]; _whereClause = (WhereClause)_queryModel.BodyClauses[2]; _selectClause = _queryModel.SelectClause; var subQueryExpressionA = (SubQueryExpression)_additionalFromClause1.FromExpression; _innerMainFromClauseA = subQueryExpressionA.QueryModel.MainFromClause; _innerWhereClauseA = (WhereClause)subQueryExpressionA.QueryModel.BodyClauses[0]; _visitor = new SubQueryFromClauseFlattener(); }
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; }
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()); }