/// <summary> /// Translates an OData $orderby represented by <see cref="OrderByClause"/> to <see cref="Expression"/> and apply to <see cref="IQueryable" />. /// </summary> /// <param name="binder">The given filter binder.</param> /// <param name="query">The given source.</param> /// <param name="orderByClause">The filter clause.</param> /// <param name="context">The query binder context.</param> /// <param name="alreadyOrdered">The boolean value indicating whether it's ordered or not.</param> /// <returns>The applied result.</returns> public static IQueryable ApplyBind(this IOrderByBinder binder, IQueryable query, OrderByClause orderByClause, QueryBinderContext context, bool alreadyOrdered) { if (binder == null) { throw Error.ArgumentNull(nameof(binder)); } if (query == null) { throw Error.ArgumentNull(nameof(query)); } if (orderByClause == null) { throw Error.ArgumentNull(nameof(orderByClause)); } if (context == null) { throw Error.ArgumentNull(nameof(context)); } OrderByBinderResult orderByResult = binder.BindOrderBy(orderByClause, context); IQueryable querySoFar = query; Type elementType = context.ElementClrType; OrderByBinderResult result = orderByResult; do { LambdaExpression orderByExpression = result.OrderByExpression as LambdaExpression; Contract.Assert(orderByExpression != null); OrderByDirection direction = result.Direction; querySoFar = ExpressionHelpers.OrderBy(querySoFar, orderByExpression, direction, elementType, alreadyOrdered); alreadyOrdered = true; result = result.ThenBy; }while (result != null); return(querySoFar); }
/// <summary> /// Translates an OData $orderby represented by <see cref="OrderByClause"/> to <see cref="Expression"/>. /// $orderby=Age /// |-- x => x.Age /// </summary> /// <param name="orderByClause">The orderby clause.</param> /// <param name="context">The query binder context.</param> /// <returns>The OrderBy binder result, <see cref="OrderByBinderResult"/>.</returns> public virtual OrderByBinderResult BindOrderBy(OrderByClause orderByClause, QueryBinderContext context) { if (orderByClause == null) { throw Error.ArgumentNull(nameof(orderByClause)); } if (context == null) { throw Error.ArgumentNull(nameof(context)); } OrderByBinderResult head = null; OrderByBinderResult last = null; for (OrderByClause clause = orderByClause; clause != null; clause = clause.ThenBy) { Expression body = Bind(clause.Expression, context); ParameterExpression parameter = context.CurrentParameter; LambdaExpression orderByLambda = Expression.Lambda(body, parameter); OrderByBinderResult result = new OrderByBinderResult(orderByLambda, clause.Direction); if (head == null) { head = result; last = result; } else { Contract.Assert(last != null); last.ThenBy = result; last = result; } } return(head); }