Exemplo n.º 1
0
        /// <summary>
        /// Add a Where clause to a query; may need to create a new query.
        /// </summary>
        /// <param name="whereClause">Clause to add.</param>
        /// <param name="context">The translation context.</param>
        /// <returns>A new query containing the specified Where clause.</returns>
        public QueryUnderConstruction AddWhereClause(SqlWhereClause whereClause, TranslationContext context)
        {
            QueryUnderConstruction result = context.PackageCurrentQueryIfNeccessary();

            whereClause        = QueryUnderConstruction.CombineWithConjunction(result.whereClause, whereClause);
            result.whereClause = whereClause;
            foreach (Binding binding in context.CurrentSubqueryBinding.TakeBindings())
            {
                result.AddBinding(binding);
            }

            return(result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Add a Where clause to a query; may need to create a new query.
        /// </summary>
        /// <param name="whereClause">Clause to add.</param>
        /// <param name="elementType">Type of element in input collection.</param>
        /// <param name="inScope">Set of parameter names in scope.</param>
        /// <returns>A new query containing the specified Where clause.</returns>
        public QueryUnderConstruction AddWhereClause(SqlWhereClause whereClause, Type elementType, HashSet <ParameterExpression> inScope)
        {
            QueryUnderConstruction.ValidateNonSubquerySupport(this);

            QueryUnderConstruction result = this;

            if (this.selectClause != null)
            {
                result = this.PackageQuery(inScope);
            }

            whereClause        = QueryUnderConstruction.CombineWithConjunction(result.whereClause, whereClause);
            result.whereClause = whereClause;
            return(result);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Flatten subqueries into a single query by substituting their expressions in the current query.
        /// </summary>
        /// <returns>A flattened query.</returns>
        public 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)
                {
                    this.selectClause = new SqlSelectClause(new SqlSelectStarSpec(), this.topSpec);
                }
                else
                {
                    this.selectClause = new SqlSelectClause(this.selectClause.SelectSpec, this.topSpec, this.selectClause.HasDistinct);
                }

                return(this);
            }

            if (this.inputQuery.orderByClause != null && this.orderByClause != null)
            {
                throw new DocumentQueryException("Multiple OrderBy is not supported.");
            }

            var flatInput   = this.inputQuery.Flatten();
            var inputSelect = flatInput.selectClause;
            var inputwhere  = flatInput.whereClause;

            SqlIdentifier          replacement     = new SqlIdentifier(this.InputParameter().Name);
            var                    composedSelect  = Substitute(inputSelect, inputSelect.TopSpec ?? this.topSpec, replacement, this.selectClause);
            var                    composedWhere   = Substitute(inputSelect.SelectSpec, replacement, this.whereClause);
            var                    composedOrderBy = Substitute(inputSelect.SelectSpec, replacement, this.orderByClause);
            var                    and             = QueryUnderConstruction.CombineWithConjunction(inputwhere, composedWhere);
            QueryUnderConstruction result          = new QueryUnderConstruction
            {
                selectClause   = composedSelect,
                whereClause    = and,
                inputQuery     = null,
                fromParameters = flatInput.fromParameters,
                orderByClause  = composedOrderBy ?? this.inputQuery.orderByClause,
            };

            return(result);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Add a Where clause to a query; may need to create a new query.
        /// </summary>
        /// <param name="whereClause">Clause to add.</param>
        /// <param name="context">The translation context.</param>
        /// <returns>A new query containing the specified Where clause.</returns>
        public QueryUnderConstruction AddWhereClause(SqlWhereClause whereClause, TranslationContext context)
        {
            QueryUnderConstruction result = this;

            if (this.ShouldBeOnNewQuery(LinqMethods.Where, 2))
            {
                result = this.PackageQuery(context.InScope, context.PeekCollection());
                context.CurrentSubqueryBinding.ShouldBeOnNewQuery = false;
            }

            whereClause        = QueryUnderConstruction.CombineWithConjunction(result.whereClause, whereClause);
            result.whereClause = whereClause;
            foreach (Binding binding in context.CurrentSubqueryBinding.TakeBindings())
            {
                result.AddBinding(binding);
            }

            return(result);
        }
Exemplo n.º 5
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);
        }