Exemple #1
0
        /// <summary>
        /// Apply the individual query to the given IQueryable in the right order.
        /// </summary>
        /// <param name="query">The original <see cref="IQueryable"/>.</param>
        /// <param name="querySettings">The settings to use in query composition.</param>
        /// <returns>The new <see cref="IQueryable"/> after the query has been applied to.</returns>
        public virtual IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings)
        {
            if (query == null)
            {
                throw Error.ArgumentNull("query");
            }

            // Construct the actual query and apply them in the following order: filter
            if (Filter != null)
            {
                query = Filter.ApplyTo(query, querySettings, _assemblyProvider);
            }

            if (OrderBy != null)
            {
                query = OrderBy.ApplyTo(query, querySettings);
            }

            if (Skip.HasValue)
            {
                query = ExpressionHelpers.Skip(query, Skip.Value, Context.ElementClrType, false);
            }

            int?take = null;

            if (querySettings.PageSize.HasValue)
            {
                take = Math.Min(querySettings.PageSize.Value, int.MaxValue);
            }
            if (Top.HasValue)
            {
                take = Math.Min(Top.Value, take ?? int.MaxValue);
            }
            if (take.HasValue)
            {
                query = ExpressionHelpers.Take(query, take.Value, Context.ElementClrType, false);
            }

            if (SelectExpand != null)
            {
                query = SelectExpand.ApplyTo(query, querySettings, _assemblyProvider);
            }

            return(query);
        }
        private IQueryable ApplyToCore(IQueryable query, ODataQuerySettings querySettings)
        {
            if (query == null)
            {
                throw Error.ArgumentNull(nameof(query));
            }

            if (querySettings == null)
            {
                throw Error.ArgumentNull(nameof(querySettings));
            }

            if (Context.ElementClrType == null)
            {
                throw Error.NotSupported(SRResources.ApplyToOnUntypedQueryOption, "ApplyTo");
            }

            return(ExpressionHelpers.Take(query, Value, query.ElementType, querySettings.EnableConstantParameterization));
        }
        /// <summary>
        /// Apply the individual query to the given IQueryable in the right order.
        /// </summary>
        /// <param name="query">The original <see cref="IQueryable"/>.</param>
        /// <param name="querySettings">The settings to use in query composition.</param>
        /// <param name="pageSize">The page size for this query</param>
        /// <param name="queryOptions"></param>
        /// <returns>The new <see cref="IQueryable"/> after the query has been applied to.</returns>
        public virtual IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings, int?pageSize,
                                          ODataQueryOptions queryOptions)
        {
            if (query == null)
            {
                throw Error.ArgumentNull("query");
            }

            // Construct the actual query and apply them in the following order: filter
            if (Filter != null)
            {
                query = Filter.ApplyTo(query, querySettings, _assemblyProvider);
            }

            var orderBy = OrderBy;

            // $skip or $top require a stable sort for predictable results.
            // Result limits require a stable sort to be able to generate a next page link.
            // If either is present in the query and we have permission,
            // generate an $orderby that will produce a stable sort.
            if (querySettings.EnsureStableOrdering &&
                ((Skip != null && queryOptions.IgnoreSkip == false) ||
                 (Top != null && queryOptions.IgnoreTop == false) ||
                 pageSize.HasValue))
            {
                // If there is no OrderBy present, we manufacture a default.
                // If an OrderBy is already present, we add any missing
                // properties necessary to make a stable sort.
                // Instead of failing early here if we cannot generate the OrderBy,
                // let the IQueryable backend fail (if it has to).
                orderBy = orderBy == null
                            ? OrderByHelper.GenerateDefaultOrderBy(Context, _serviceProvider)
                            : OrderByHelper.EnsureStableSortOrderBy(orderBy, Context, _serviceProvider);
            }

            // First apply $apply
            // Section 3.15 of the spec http://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/cs01/odata-data-aggregation-ext-v4.0-cs01.html#_Toc378326311
            if (Apply != null)
            {
                query = Apply.ApplyTo(query, querySettings, _assemblyProvider);
                Request.ODataFeature().ApplyClause = Apply.ApplyClause;
                Context.ElementClrType = Apply.ResultClrType;
            }

            if (orderBy != null && Apply == null)
            {
                query = orderBy.ApplyTo(query, querySettings);
            }

            if (Skip.HasValue && queryOptions.IgnoreSkip == false)
            {
                query = ExpressionHelpers.Skip(query, Skip.Value, Context.ElementClrType, false);
            }

            int?take = null;

            if (querySettings.PageSize.HasValue)
            {
                take = Math.Min(querySettings.PageSize.Value, int.MaxValue);
            }
            if (Top.HasValue && queryOptions.IgnoreTop == false)
            {
                take = Math.Min(Top.Value, take ?? int.MaxValue);
            }
            if (take.HasValue)
            {
                query = ExpressionHelpers.Take(query, take.Value, Context.ElementClrType, false);
            }

            if (SelectExpand != null)
            {
                query = SelectExpand.ApplyTo(query, querySettings, _assemblyProvider);
            }

            if (CountQueryOption != null)
            {
                if (Request.ODataFeature().TotalCountFunc == null)
                {
                    Func <long> countFunc = CountQueryOption.GetEntityCountFunc(query);
                    if (countFunc != null)
                    {
                        Request.ODataFeature().TotalCountFunc = countFunc;
                    }
                }

                if (ODataCountMediaTypeMapping.IsCountRequest(Request.HttpContext))
                {
                    return(query);
                }
            }
            if (pageSize.HasValue && Apply == null)
            {
                bool resultsLimited;
                query = LimitResults(query, pageSize.Value, out resultsLimited);
                if (resultsLimited && Request.GetDisplayUrl() != null && new Uri(Request.GetDisplayUrl()).IsAbsoluteUri&& Request.ODataFeature().NextLink == null)
                {
                    Uri nextPageLink = Request.GetNextPageLink(pageSize.Value);
                    Request.ODataFeature().NextLink = nextPageLink;
                }
            }
            return(query);
        }