/// <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); }
/// <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); }
/// <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); }