public static IQueryable<TElement> Apply<TElement>(IQueryable<TElement> query, ODataQueryExpression oDataQuery, out IQueryable<TElement> inlineCountQuery) { var finalQuery = query; if (oDataQuery.Filter != null) { var parameter = Expression.Parameter(typeof(TElement)); var predicate = Expression.Lambda<Func<TElement, bool>>(Translate(parameter, oDataQuery.Filter), parameter); var denormalizedPredicate = (Expression<Func<TElement, bool>>)ODataEntity.Denormalize(predicate); finalQuery = finalQuery.Where(denormalizedPredicate); } inlineCountQuery = finalQuery; for (var i = 0; i < oDataQuery.OrderBy.Count; ++i) { finalQuery = ApplyOrderBy(finalQuery, oDataQuery.OrderBy[i], isPrimarySort: i == 0); } if (oDataQuery.Skip > 0) { finalQuery = finalQuery.Skip(oDataQuery.Skip); } if (oDataQuery.Top.HasValue) { finalQuery = finalQuery.Take(oDataQuery.Top.Value); } return finalQuery; }
private static IQueryable<TElement> ApplyOrderBy<TElement>(IQueryable<TElement> query, ODataSortKeyExpression sortKey, bool isPrimarySort) { var parameter = Expression.Parameter(typeof(TElement)); var translated = Translate(parameter, sortKey.Expression); var lambda = Expression.Lambda(translated, parameter); var methodName = (isPrimarySort ? "OrderBy" : "ThenBy") + (sortKey.Descending ? "Descending" : string.Empty); MethodInfo method; switch (methodName) { case "OrderBy": method = Helpers.GetMethod((IQueryable<object> q) => q.OrderBy(o => o)); break; case "OrderByDescending": method = Helpers.GetMethod((IQueryable<object> q) => q.OrderByDescending(o => o)); break; case "ThenBy": method = Helpers.GetMethod((IOrderedQueryable<object> q) => q.ThenBy(o => o)); break; case "ThenByDescending": method = Helpers.GetMethod((IOrderedQueryable<object> q) => q.ThenByDescending(o => o)); break; default: throw Throw.UnexpectedCase(methodName); } var denormalizedLambda = ODataEntity.Denormalize(lambda); var result = method.GetGenericMethodDefinition() .MakeGenericMethod(lambda.Type.GetGenericArguments(typeof(Func<,>))) .Invoke(null, new object[] { query, denormalizedLambda }); return (IQueryable<TElement>)result; }
public static Result Project(IQueryable query, IReadOnlyList <ODataSelectColumnExpression> select) { if (select.Count == 0) { return(Project(query, new[] { ODataExpression.SelectStar() })); } Throw <NotSupportedException> .If(select.Any(sc => !sc.AllColumns && sc.Type == ODataExpressionType.Complex), "Selecting a complex type is only supported when selecting all columns of that type (with '/*')"); var mapping = BuildMapping(select); var parameter = Expression.Parameter(query.ElementType); var newExpression = BuildNewExpression(parameter, mapping); var lambda = Expression.Lambda(newExpression, parameter); var selectMethod = Helpers.GetMethod((IQueryable <object> q) => q.Select(o => o)) .GetGenericMethodDefinition() .MakeGenericMethod(query.ElementType, newExpression.Type); var denormalizedLambda = ODataEntity.Denormalize(lambda); var projected = (IQueryable)selectMethod.Invoke(null, new object[] { query, denormalizedLambda }); var resultMapping = BuildResultMapping(projected.ElementType, mapping); return(new Result(projected, resultMapping)); }