Ejemplo n.º 1
0
        private static FromParameterBindings CombineInputParameters(FromParameterBindings inputQueryParams, FromParameterBindings currentQueryParams)
        {
            HashSet <string> seen = new HashSet <string>();

            foreach (Binding binding in inputQueryParams.GetBindings())
            {
                seen.Add(binding.Parameter.Name);
            }

            FromParameterBindings fromParams = inputQueryParams;

            foreach (FromParameterBindings.Binding binding in currentQueryParams.GetBindings())
            {
                if (binding.ParameterDefinition != null && !seen.Contains(binding.Parameter.Name))
                {
                    fromParams.Add(binding);
                    seen.Add(binding.Parameter.Name);
                }
            }

            return(fromParams);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Flatten subqueries into a single query by substituting their expressions in the current query.
        /// </summary>
        /// <returns>A flattened query.</returns>
        private QueryUnderConstruction Flatten()
        {
            // SELECT fo(y) FROM y IN (SELECT fi(x) FROM x WHERE gi(x)) WHERE go(y)
            // is translated by substituting fi(x) for y in the outer query
            // producing
            // SELECT fo(fi(x)) FROM x WHERE gi(x) AND (go(fi(x))
            if (this.inputQuery == null)
            {
                // we are flat already
                if (this.selectClause == null)
                {
                    // If selectClause doesn't exists, use SELECT v0 where v0 is the input parameter, instead of SELECT *.
                    string parameterName = this.fromParameters.GetInputParameter().Name;
                    SqlScalarExpression parameterExpression = SqlPropertyRefScalarExpression.Create(null, SqlIdentifier.Create(parameterName));
                    this.selectClause = SqlSelectClause.Create(SqlSelectValueSpec.Create(parameterExpression));
                }
                else
                {
                    this.selectClause = SqlSelectClause.Create(this.selectClause.SelectSpec, this.topSpec, this.selectClause.HasDistinct);
                }

                return(this);
            }

            QueryUnderConstruction flatInput   = this.inputQuery.Flatten();
            SqlSelectClause        inputSelect = flatInput.selectClause;
            SqlWhereClause         inputwhere  = flatInput.whereClause;

            // Determine the paramName to be replaced in the current query
            // It should be the top input parameter name which is not binded in this collection.
            // That is because if it has been binded before, it has global scope and should not be replaced.
            string           paramName        = null;
            HashSet <string> inputQueryParams = new HashSet <string>();

            foreach (Binding binding in this.inputQuery.fromParameters.GetBindings())
            {
                inputQueryParams.Add(binding.Parameter.Name);
            }

            foreach (Binding binding in this.fromParameters.GetBindings())
            {
                if (binding.ParameterDefinition == null || inputQueryParams.Contains(binding.Parameter.Name))
                {
                    paramName = binding.Parameter.Name;
                }
            }

            SqlIdentifier         replacement     = SqlIdentifier.Create(paramName);
            SqlSelectClause       composedSelect  = Substitute(inputSelect, inputSelect.TopSpec ?? this.topSpec, replacement, this.selectClause);
            SqlWhereClause        composedWhere   = Substitute(inputSelect.SelectSpec, replacement, this.whereClause);
            SqlOrderbyClause      composedOrderBy = Substitute(inputSelect.SelectSpec, replacement, this.orderByClause);
            SqlWhereClause        and             = QueryUnderConstruction.CombineWithConjunction(inputwhere, composedWhere);
            FromParameterBindings fromParams      = QueryUnderConstruction.CombineInputParameters(flatInput.fromParameters, this.fromParameters);
            SqlOffsetSpec         offsetSpec;
            SqlLimitSpec          limitSpec;

            if (flatInput.offsetSpec != null)
            {
                offsetSpec = flatInput.offsetSpec;
                limitSpec  = flatInput.limitSpec;
            }
            else
            {
                offsetSpec = this.offsetSpec;
                limitSpec  = this.limitSpec;
            }
            QueryUnderConstruction result = new QueryUnderConstruction(this.aliasCreatorFunc)
            {
                selectClause   = composedSelect,
                whereClause    = and,
                inputQuery     = null,
                fromParameters = flatInput.fromParameters,
                orderByClause  = composedOrderBy ?? this.inputQuery.orderByClause,
                offsetSpec     = offsetSpec,
                limitSpec      = limitSpec,
                alias          = new Lazy <ParameterExpression>(() => this.Alias)
            };

            return(result);
        }
Ejemplo n.º 3
0
 public QueryUnderConstruction()
 {
     this.fromParameters = new FromParameterBindings();
 }