/// <summary> /// Parses the $orderby expression. /// </summary> /// <param name="orderBy">The $orderby expression string to parse.</param> /// <returns>The enumeraion of lexical tokens representing order by tokens.</returns> internal IEnumerable <OrderByToken> ParseOrderBy(string orderBy) { Debug.Assert(orderBy != null, "orderBy != null"); this.recursionDepth = 0; this.lexer = CreateLexerForFilterOrOrderByOrApplyExpression(orderBy); List <OrderByToken> orderByTokens = new List <OrderByToken>(); while (true) { QueryToken expression = this.ParseExpression(); bool ascending = true; if (this.TokenIdentifierIs(ExpressionConstants.KeywordAscending)) { this.lexer.NextToken(); } else if (this.TokenIdentifierIs(ExpressionConstants.KeywordDescending)) { this.lexer.NextToken(); ascending = false; } OrderByToken orderByToken = new OrderByToken(expression, ascending ? OrderByDirection.Ascending : OrderByDirection.Descending); orderByTokens.Add(orderByToken); if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.Comma) { break; } this.lexer.NextToken(); } this.lexer.ValidateToken(ExpressionTokenKind.End); return(new ReadOnlyCollection <OrderByToken>(orderByTokens)); }
/// <summary> /// Visits an OrderByToken /// </summary> /// <param name="tokenIn">The OrderByToken to bind</param> /// <returns>An OrderByClause bound to this OrderByToken</returns> public virtual T Visit(OrderByToken tokenIn) { throw new NotImplementedException(); }
/// <summary> /// Processes the specified order-by token. /// </summary> /// <param name="state">State to use for binding.</param> /// <param name="thenBy"> The next OrderBy node, or null if there is no orderby after this.</param> /// <param name="orderByToken">The order-by token to bind.</param> /// <returns>Returns the combined entityCollection including the ordering.</returns> private OrderByClause ProcessSingleOrderBy(BindingState state, OrderByClause thenBy, OrderByToken orderByToken) { ExceptionUtils.CheckArgumentNotNull(state, "state"); ExceptionUtils.CheckArgumentNotNull(orderByToken, "orderByToken"); QueryNode expressionNode = this.bindMethod(orderByToken.Expression); // The order-by expressions need to be primitive / enumeration types SingleValueNode expressionResultNode = expressionNode as SingleValueNode; if (expressionResultNode == null || (expressionResultNode.TypeReference != null && !expressionResultNode.TypeReference.IsODataPrimitiveTypeKind() && !expressionResultNode.TypeReference.IsODataEnumTypeKind() && !expressionResultNode.TypeReference.IsODataTypeDefinitionTypeKind())) { throw new ODataException(ODataErrorStrings.MetadataBinder_OrderByExpressionNotSingleValue); } OrderByClause orderByNode = new OrderByClause( thenBy, expressionResultNode, orderByToken.Direction, state.ImplicitRangeVariable); return(orderByNode); }