/// <summary> /// Find and flatten the prefix set of queries into a single query by substituting their expressions. /// </summary> /// <returns>The query that has been flatten</returns> public QueryUnderConstruction FlattenAsPossible() { // Flatten should be done when the current query can be translated without the need of using sub query // The cases that need to use sub query are: // 1. Select clause appears after Distinct // 2. There are any operations after Take // 3. There are nested Select, Where or OrderBy QueryUnderConstruction parentQuery = null; QueryUnderConstruction flattenQuery = null; bool seenSelect = false; bool seenAnyOp = false; for (QueryUnderConstruction query = this; query != null; query = query.inputQuery) { foreach (Binding binding in query.fromParameters.GetBindings()) { if ((binding.ParameterDefinition != null) && (binding.ParameterDefinition is SqlSubqueryCollection)) { flattenQuery = this; break; } } if (flattenQuery != null) { break; } if ((query.topSpec != null && seenAnyOp) || (query.selectClause != null && query.selectClause.HasDistinct && seenSelect)) { parentQuery.inputQuery = query.FlattenAsPossible(); flattenQuery = this; break; } seenSelect = seenSelect || ((query.selectClause != null) && !(query.selectClause.HasDistinct)); seenAnyOp = true; parentQuery = query; } if (flattenQuery == null) { flattenQuery = this.Flatten(); } return(flattenQuery); }
/// <summary> /// Find and flatten the prefix set of queries into a single query by substituting their expressions. /// </summary> /// <returns>The query that has been flatten</returns> public QueryUnderConstruction FlattenAsPossible() { // Flatten should be done when the current query can be translated without the need of using sub query // The cases that need to use sub query are: // 1. Select clause appears after Distinct // 2. There are any operations after Take that is not a pure Select. // 3. There are nested Select, Where or OrderBy QueryUnderConstruction parentQuery = null; QueryUnderConstruction flattenQuery = null; bool seenSelect = false; bool seenAnyNonSelectOp = false; for (QueryUnderConstruction query = this; query != null; query = query.inputQuery) { foreach (Binding binding in query.fromParameters.GetBindings()) { if ((binding.ParameterDefinition != null) && (binding.ParameterDefinition is SqlSubqueryCollection)) { flattenQuery = this; break; } } // In Select -> SelectMany cases, fromParameter substitution is not yet supported . // Therefore these are un-flattenable. if (query.inputQuery != null && (query.fromParameters.GetBindings().First().Parameter.Name == query.inputQuery.Alias.Name) && query.fromParameters.GetBindings().Any(b => b.ParameterDefinition != null)) { flattenQuery = this; break; } if (flattenQuery != null) { break; } if (((query.topSpec != null || query.offsetSpec != null || query.limitSpec != null) && seenAnyNonSelectOp) || (query.selectClause != null && query.selectClause.HasDistinct && seenSelect)) { parentQuery.inputQuery = query.FlattenAsPossible(); flattenQuery = this; break; } seenSelect = seenSelect || ((query.selectClause != null) && !(query.selectClause.HasDistinct)); seenAnyNonSelectOp |= (query.whereClause != null) || (query.orderByClause != null) || (query.topSpec != null) || (query.offsetSpec != null) || (query.fromParameters.GetBindings().Any(b => b.ParameterDefinition != null)) || ((query.selectClause != null) && ((query.selectClause.HasDistinct) || (this.HasSelectAggregate()))); parentQuery = query; } if (flattenQuery == null) { flattenQuery = this.Flatten(); } return(flattenQuery); }