/// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override Expression VisitSelect(SelectExpression selectExpression)
        {
            Check.NotNull(selectExpression, nameof(selectExpression));

            _sqlBuilder.Append("SELECT ");

            if (selectExpression.IsDistinct)
            {
                _sqlBuilder.Append("DISTINCT ");
            }

            if (selectExpression.Projection.Count > 0)
            {
                if (selectExpression.Projection.Any(p => !string.IsNullOrEmpty(p.Alias) && p.Alias != p.Name) &&
                    !selectExpression.Projection.Any(p => p.Expression is SqlFunctionExpression))    // Aggregates are not allowed
                {
                    _useValueProjection = true;
                    _sqlBuilder.Append("VALUE {");
                    GenerateList(selectExpression.Projection, e => Visit(e));
                    _sqlBuilder.Append("}");
                    _useValueProjection = false;
                }
                else
                {
                    GenerateList(selectExpression.Projection, e => Visit(e));
                }
            }
            else
            {
                _sqlBuilder.Append("1");
            }

            _sqlBuilder.AppendLine();

            _sqlBuilder.Append("FROM root ");
            Visit(selectExpression.FromExpression);
            _sqlBuilder.AppendLine();

            if (selectExpression.Predicate != null)
            {
                _sqlBuilder.Append("WHERE ");
                Visit(selectExpression.Predicate);
            }

            if (selectExpression.Orderings.Any())
            {
                _sqlBuilder.AppendLine().Append("ORDER BY ");

                GenerateList(selectExpression.Orderings, e => Visit(e));
            }

            if (selectExpression.Offset != null ||
                selectExpression.Limit != null)
            {
                _sqlBuilder.AppendLine().Append("OFFSET ");

                if (selectExpression.Offset != null)
                {
                    Visit(selectExpression.Offset);
                }
                else
                {
                    _sqlBuilder.Append("0");
                }

                _sqlBuilder.Append(" LIMIT ");

                if (selectExpression.Limit != null)
                {
                    Visit(selectExpression.Limit);
                }
                else
                {
                    // TODO: See Issue#18923
                    throw new InvalidOperationException(CosmosStrings.OffsetRequiresLimit);
                }
            }

            return(selectExpression);
        }
Exemple #2
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override Expression VisitChildren(ExpressionVisitor visitor)
        {
            Check.NotNull(visitor, nameof(visitor));

            var changed = false;

            var projections = new List <ProjectionExpression>();
            IDictionary <ProjectionMember, Expression> projectionMapping;

            if (Projection.Any())
            {
                projectionMapping = _projectionMapping;
                foreach (var item in Projection)
                {
                    var projection = (ProjectionExpression)visitor.Visit(item);
                    projections.Add(projection);

                    changed |= projection != item;
                }
            }
            else
            {
                projectionMapping = new Dictionary <ProjectionMember, Expression>();
                foreach (var mapping in _projectionMapping)
                {
                    var newProjection = visitor.Visit(mapping.Value);
                    changed |= newProjection != mapping.Value;

                    projectionMapping[mapping.Key] = newProjection;
                }
            }

            var fromExpression = (RootReferenceExpression)visitor.Visit(FromExpression);

            changed |= fromExpression != FromExpression;

            var predicate = (SqlExpression)visitor.Visit(Predicate);

            changed |= predicate != Predicate;

            var orderings = new List <OrderingExpression>();

            foreach (var ordering in _orderings)
            {
                var orderingExpression = (SqlExpression)visitor.Visit(ordering.Expression);
                changed |= orderingExpression != ordering.Expression;
                orderings.Add(ordering.Update(orderingExpression));
            }

            var offset = (SqlExpression)visitor.Visit(Offset);

            changed |= offset != Offset;

            var limit = (SqlExpression)visitor.Visit(Limit);

            changed |= limit != Limit;

            if (changed)
            {
                var newSelectExpression = new SelectExpression(projections, fromExpression, orderings)
                {
                    _projectionMapping = projectionMapping,
                    Predicate          = predicate,
                    Offset             = offset,
                    Limit      = limit,
                    IsDistinct = IsDistinct
                };

                return(newSelectExpression);
            }

            return(this);
        }
Exemple #3
0
 /// <summary>
 ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
 ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
 ///     any release. You should only use it directly in your code with extreme caution and knowing that
 ///     doing so can result in application failures when updating to a new Entity Framework Core release.
 /// </summary>
 protected abstract Expression VisitSelect([NotNull] SelectExpression selectExpression);
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override Expression VisitSelect(SelectExpression selectExpression)
        {
            Check.NotNull(selectExpression, nameof(selectExpression));

            _sqlBuilder.Append("SELECT ");

            if (selectExpression.IsDistinct)
            {
                _sqlBuilder.Append("DISTINCT ");
            }

            if (selectExpression.Projection.Any())
            {
                GenerateList(selectExpression.Projection, e => Visit(e));
            }
            else
            {
                _sqlBuilder.Append("1");
            }

            _sqlBuilder.AppendLine();

            _sqlBuilder.Append("FROM root ");
            Visit(selectExpression.FromExpression);
            _sqlBuilder.AppendLine();

            if (selectExpression.Predicate != null)
            {
                _sqlBuilder.Append("WHERE ");
                Visit(selectExpression.Predicate);
            }

            if (selectExpression.Orderings.Any())
            {
                _sqlBuilder.AppendLine().Append("ORDER BY ");

                GenerateList(selectExpression.Orderings, e => Visit(e));
            }

            if (selectExpression.Offset != null ||
                selectExpression.Limit != null)
            {
                _sqlBuilder.AppendLine().Append("OFFSET ");

                if (selectExpression.Offset != null)
                {
                    Visit(selectExpression.Offset);
                }
                else
                {
                    _sqlBuilder.Append("0");
                }

                _sqlBuilder.Append(" LIMIT ");

                if (selectExpression.Limit != null)
                {
                    Visit(selectExpression.Limit);
                }
                else
                {
                    // TODO: See Issue#18923
                    throw new InvalidOperationException("Cosmos Sql API does not support Offset without Limit.");
                }
            }

            return(selectExpression);
        }
 /// <summary>
 ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
 ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
 ///     any release. You should only use it directly in your code with extreme caution and knowing that
 ///     doing so can result in application failures when updating to a new Entity Framework Core release.
 /// </summary>
 protected abstract Expression VisitSelect(SelectExpression selectExpression);
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override Expression VisitSelect(SelectExpression selectExpression)
        {
            _sqlBuilder.Append("SELECT ");

            if (selectExpression.IsDistinct)
            {
                _sqlBuilder.Append("DISTINCT ");
            }

            if (selectExpression.Projection.Any())
            {
                GenerateList(selectExpression.Projection, e => Visit(e));
            }
            else
            {
                _sqlBuilder.Append("1");
            }

            _sqlBuilder.AppendLine();

            _sqlBuilder.Append("FROM root ");
            Visit(selectExpression.FromExpression);
            _sqlBuilder.AppendLine();

            if (selectExpression.Predicate != null)
            {
                _sqlBuilder.Append("WHERE ");
                Visit(selectExpression.Predicate);
            }

            if (selectExpression.Orderings.Any())
            {
                _sqlBuilder.AppendLine().Append("ORDER BY ");

                GenerateList(selectExpression.Orderings, e => Visit(e));
            }

            if (selectExpression.Offset != null ||
                selectExpression.Limit != null)
            {
                _sqlBuilder.AppendLine().Append("OFFSET ");

                if (selectExpression.Offset != null)
                {
                    Visit(selectExpression.Offset);
                }
                else
                {
                    _sqlBuilder.Append("0");
                }

                _sqlBuilder.Append(" LIMIT ");

                if (selectExpression.Limit != null)
                {
                    Visit(selectExpression.Limit);
                }
                else
                {
                    throw new InvalidOperationException(CoreStrings.QueryFailed(selectExpression.Print(), GetType().Name));
                }
            }

            return(selectExpression);
        }