/// <summary> /// Evaluates the specified expression. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <returns>Value of the expression.</returns> public virtual QueryValue Visit(LinqOrderByExpression expression) { var keySelectors = expression.KeySelectors; var areDescending = expression.AreDescending; var source = this.Evaluate(expression.Source) as QueryCollectionValue; var ordering = new QueryOrdering(); for (int i = 0; i < keySelectors.Count; i++) { Func <object, QueryScalarValue> selector = this.CreateKeySelector(keySelectors[i]); if (areDescending[i]) { ordering = ordering.Descending(selector); } else { ordering = ordering.Ascending(selector); } } return(source.OrderBy(ordering)); }
/// <summary> /// Resolves types for the specified expression. /// </summary> /// <param name="expression">The expression to resolve types for.</param> /// <returns>Expression with resolved types.</returns> public QueryExpression Visit(LinqOrderByExpression expression) { var source = this.ResolveTypes(expression.Source); var sourceType = ValidateSourceIsACollection(source); var keySelectors = expression.KeySelectors.Select(s => this.ResolveLambdaTypes(s, sourceType)).ToArray(); return(LinqBuilder.OrderBy(source, keySelectors, expression.AreDescending, sourceType)); }
/// <summary> /// Replaces the given expression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Replaced expression.</returns> public virtual QueryExpression Visit(LinqOrderByExpression expression) { QueryExpression source = this.ReplaceExpression(expression.Source); var keySelectors = expression.KeySelectors.Select(this.ReplaceExpression).Cast <LinqLambdaExpression>().ToArray(); if (HasChanged(expression.Source, source) || HasChanged(expression.KeySelectors, keySelectors)) { // using internal overload, because there may be multiple keySelectors, public overloads only allow to set one at at time return(LinqBuilder.OrderBy(source, keySelectors, expression.AreDescending, expression.ExpressionType)); } return(expression); }
/// <summary> /// Evaluates the specified expression. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <returns>Value of the expression.</returns> public override QueryValue Visit(LinqOrderByExpression expression) { var value = this.VisitCollectionElementPrimitiveOrComplexTypeError( expression, delegate { return(base.Visit(expression)); }); var collection = value as QueryCollectionValue; var strategy = collection.Type.ElementType.EvaluationStrategy as ILinqToAstoriaQueryEvaluationStrategy; ExceptionUtilities.CheckObjectNotNull(strategy, "Cannot get astoria-specific evaluation strategy from collection value."); if (strategy.IsCollectionOrderPredictable) { return(QueryCollectionValue.Create(collection.Type.ElementType, collection.Elements, true)); } return(value); }
/// <summary> /// Visits a QueryExpression tree whose root node is the LinqOrderByExpression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Uri query string representing the expression.</returns> public override string Visit(LinqOrderByExpression expression) { string source = this.ComputeUriInternal(expression.Source); List <string> orderby = new List <string>(); for (int i = 0; i < expression.KeySelectors.Count; i++) { var order = this.ExpressionConverter.Convert(expression.KeySelectors[i].Body); if (expression.AreDescending[i]) { order += " desc"; } orderby.Add(order); } this.SetOrderByQueryOption(string.Join(",", orderby.ToArray())); this.hasQueryOption = true; return(source); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqOrderByExpression expression) { CodeExpression source = this.GenerateCode(expression.Source); CodeExpression result = source; for (int i = 0; i < expression.KeySelectors.Count; i++) { var keySelector = this.GenerateCode(expression.KeySelectors[i]); var isDescending = expression.AreDescending[i]; string methodName = i == 0 ? "OrderBy" : "ThenBy"; if (isDescending) { methodName += "Descending"; } result = Code.Call(result, methodName, keySelector); } return result; }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqOrderByExpression expression) { CodeExpression source = this.GenerateCode(expression.Source); CodeExpression result = source; for (int i = 0; i < expression.KeySelectors.Count; i++) { var keySelector = this.GenerateCode(expression.KeySelectors[i]); var isDescending = expression.AreDescending[i]; string methodName = i == 0 ? "OrderBy" : "ThenBy"; if (isDescending) { methodName += "Descending"; } result = Code.Call(result, methodName, keySelector); } return(result); }
/// <summary> /// Filters the specified expression. Skip orderby expression. /// </summary> /// <param name="expression">The expression to filter.</param> /// <returns>The filtered expression</returns> public override QueryExpression Visit(LinqOrderByExpression expression) { return(expression.Source.Accept(this)); }
/// <summary> /// Visits a QueryExpression tree whose root node is the LinqOrderByExpression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Uri query string representing the expression.</returns> public override string Visit(LinqOrderByExpression expression) { string source = this.ComputeUriInternal(expression.Source); List<string> orderby = new List<string>(); for (int i = 0; i < expression.KeySelectors.Count; i++) { var order = this.ExpressionConverter.Convert(expression.KeySelectors[i].Body); if (expression.AreDescending[i]) { order += " desc"; } orderby.Add(order); } this.SetOrderByQueryOption(string.Join(",", orderby.ToArray())); this.hasQueryOption = true; return source; }
/// <summary> /// Visits a QueryExpression tree whose root node is the LinqOrderByExpression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Uri query string representing the expression.</returns> public virtual string Visit(LinqOrderByExpression expression) { throw new TaupoNotSupportedException("Not supported"); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public abstract CodeExpression Visit(LinqOrderByExpression expression);
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqOrderByExpression expression) { var source = this.GenerateCode(expression.Source); var codeQuerySource = source as CodeQueryExpression; string inputParameterName = this.GetInputParameterName(codeQuerySource); string groupParameterName = this.GetGroupParameterName(codeQuerySource); List <CodeExpression> orderByKeySelectors = new List <CodeExpression>(); List <bool> areDescending = new List <bool>(); for (int i = 0; i < expression.KeySelectors.Count; i++) { var prm = expression.KeySelectors[i].Parameters.Single(); var newPrm = new CodeParameterDeclarationExpression(new CodeImplicitTypeReference(), inputParameterName); this.ParameterNamesDictionary.Add(prm, newPrm); CodeExpression keyselector; try { keyselector = this.GenerateCode(expression.KeySelectors[i].Body); } finally { this.ParameterNamesDictionary.Remove(prm); } orderByKeySelectors.Add(keyselector); if (expression.AreDescending[i]) { areDescending.Add(true); } else { areDescending.Add(false); } } if (codeQuerySource != null) { if (codeQuerySource.GroupByKeySelector == null && codeQuerySource.Select == null) { return(new CodeQueryExpression( codeQuerySource.InputParameterName, codeQuerySource.GroupParameterName, codeQuerySource.From, codeQuerySource.Where, orderByKeySelectors, areDescending, codeQuerySource.GroupByKeySelector, codeQuerySource.Select)); } else { return(new CodeQueryExpression( inputParameterName, groupParameterName, codeQuerySource, null, orderByKeySelectors, areDescending, null, null)); } } else { return(new CodeQueryExpression( inputParameterName, groupParameterName, source, null, orderByKeySelectors, areDescending, null, null)); } }
/// <summary> /// Processes the $orderby portion of the uri. Will also add special ordering if the response would be paged. /// </summary> /// <param name="source">The source expression</param> /// <returns>The result of processing the orderby</returns> private QueryExpression ProcessOrderBy(QueryExpression source) { ExceptionUtilities.CheckArgumentNotNull(source, "source"); var queryBasedUri = this.currentUri as QueryBasedODataUri; if (queryBasedUri != null && queryBasedUri.OrderByExpressions.Count > 0) { LinqOrderByExpression orderedQuery = null; // rebuild the orderby expression using OrderBy and ThenBy foreach (var orderby in queryBasedUri.OrderByExpressions) { ExceptionUtilities.Assert(orderby.AreDescending.Count == orderby.KeySelectors.Count, "Orderby expression had mismatched counts"); ExceptionUtilities.Assert(orderby.KeySelectors.Count > 0, "Orderby expression did not have any key selectors"); // handle the first key selector seperately, since the remainder will need to use ThenBy int startIndex = 0; if (orderedQuery == null) { var ascending = !orderby.AreDescending[0]; var lambda = orderby.KeySelectors[0]; startIndex = 1; if (ascending) { orderedQuery = source.OrderBy(o => this.RewriteLambda(o, lambda)); } else { orderedQuery = source.OrderByDescending(o => this.RewriteLambda(o, lambda)); } } // handle the remaining key selectors for (int i = startIndex; i < orderby.AreDescending.Count; i++) { var ascending = !orderby.AreDescending[i]; var lambda = orderby.KeySelectors[i]; if (ascending) { orderedQuery = orderedQuery.ThenBy(o => this.RewriteLambda(o, lambda)); } else { orderedQuery = orderedQuery.ThenByDescending(o => this.RewriteLambda(o, lambda)); } } } source = orderedQuery; } else { // if this uri was not built from a query, then we cannot handle orderby expressions var orderByString = this.currentUri.OrderBy; ExceptionUtilities.Assert(string.IsNullOrEmpty(orderByString), "Non-query-based uri had non-empty orderby string '{0}' which cannot be processed", orderByString); } // add ordering if the response would be paged if (this.IsPaged()) { source = this.AddOrderingForPaging(source); } return(source); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqOrderByExpression expression) { var source = this.GenerateCode(expression.Source); var codeQuerySource = source as CodeQueryExpression; string inputParameterName = this.GetInputParameterName(codeQuerySource); string groupParameterName = this.GetGroupParameterName(codeQuerySource); List<CodeExpression> orderByKeySelectors = new List<CodeExpression>(); List<bool> areDescending = new List<bool>(); for (int i = 0; i < expression.KeySelectors.Count; i++) { var prm = expression.KeySelectors[i].Parameters.Single(); var newPrm = new CodeParameterDeclarationExpression(new CodeImplicitTypeReference(), inputParameterName); this.ParameterNamesDictionary.Add(prm, newPrm); CodeExpression keyselector; try { keyselector = this.GenerateCode(expression.KeySelectors[i].Body); } finally { this.ParameterNamesDictionary.Remove(prm); } orderByKeySelectors.Add(keyselector); if (expression.AreDescending[i]) { areDescending.Add(true); } else { areDescending.Add(false); } } if (codeQuerySource != null) { if (codeQuerySource.GroupByKeySelector == null && codeQuerySource.Select == null) { return new CodeQueryExpression( codeQuerySource.InputParameterName, codeQuerySource.GroupParameterName, codeQuerySource.From, codeQuerySource.Where, orderByKeySelectors, areDescending, codeQuerySource.GroupByKeySelector, codeQuerySource.Select); } else { return new CodeQueryExpression( inputParameterName, groupParameterName, codeQuerySource, null, orderByKeySelectors, areDescending, null, null); } } else { return new CodeQueryExpression( inputParameterName, groupParameterName, source, null, orderByKeySelectors, areDescending, null, null); } }