/// <summary> /// Applies the query to the given entity using the given <see cref="ODataQuerySettings"/>. /// </summary> /// <param name="entity">The original entity.</param> /// <param name="querySettings">The <see cref="ODataQuerySettings"/> that contains all the query application related settings.</param> /// <returns>The new entity after the $select and $expand query has been applied to.</returns> /// <remarks>Only $select and $expand query options can be applied on single entities. This method throws if the query contains any other /// query options.</remarks> public virtual object ApplyTo(object entity, ODataQuerySettings querySettings) { if (entity == null) { throw Error.ArgumentNull("entity"); } if (querySettings == null) { throw Error.ArgumentNull("querySettings"); } if (Filter != null || OrderBy != null || Top != null || Skip != null || Count != null) { throw Error.InvalidOperation(SRResources.NonSelectExpandOnSingleEntity); } if (SelectExpand != null) { SelectExpandClause processedClause = SelectExpand.ProcessLevels(); SelectExpandQueryOption newSelectExpand = new SelectExpandQueryOption( SelectExpand.RawSelect, SelectExpand.RawExpand, SelectExpand.Context, processedClause); Request.ODataProperties().SelectExpandClause = processedClause; return(newSelectExpand.ApplyTo(entity, querySettings)); } return(entity); }
private T ApplySelectExpand <T>(T entity, ODataQuerySettings querySettings) { var result = default(T); bool selectAvailable = IsAvailableODataQueryOption(SelectExpand.RawSelect, AllowedQueryOptions.Select); bool expandAvailable = IsAvailableODataQueryOption(SelectExpand.RawExpand, AllowedQueryOptions.Expand); if (selectAvailable || expandAvailable) { if ((!selectAvailable && SelectExpand.RawSelect != null) || (!expandAvailable && SelectExpand.RawExpand != null)) { SelectExpand = new SelectExpandQueryOption( selectAvailable ? RawValues.Select : null, expandAvailable ? RawValues.Expand : null, SelectExpand.Context); } SelectExpandClause processedClause = SelectExpand.ProcessLevels(); SelectExpandQueryOption newSelectExpand = new SelectExpandQueryOption( SelectExpand.RawSelect, SelectExpand.RawExpand, SelectExpand.Context, processedClause); InternalRequest.Context.SelectExpandClause = processedClause; var type = typeof(T); if (type == typeof(IQueryable)) { result = (T)newSelectExpand.ApplyTo((IQueryable)entity, querySettings); } else if (type == typeof(object)) { result = (T)newSelectExpand.ApplyTo(entity, querySettings); } } return(result); }
/// <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"); } if (querySettings == null) { throw Error.ArgumentNull("querySettings"); } IQueryable result = query; // Construct the actual query and apply them in the following order: filter, orderby, skip, top if (Filter != null) { result = Filter.ApplyTo(result, querySettings, _assembliesResolver); } if (Count != null) { if (Request.ODataProperties().TotalCount == null) { long?count = Count.GetEntityCount(result); if (count.HasValue) { Request.ODataProperties().TotalCount = count.Value; } } if (ODataCountMediaTypeMapping.IsCountRequest(Request)) { return(result); } } OrderByQueryOption 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 || Top != null || querySettings.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 ? GenerateDefaultOrderBy(Context) : EnsureStableSortOrderBy(orderBy, Context); } if (orderBy != null) { result = orderBy.ApplyTo(result, querySettings); } if (Skip != null) { result = Skip.ApplyTo(result, querySettings); } if (Top != null) { result = Top.ApplyTo(result, querySettings); } if (SelectExpand != null) { SelectExpandClause processedClause = SelectExpand.ProcessLevels(); SelectExpandQueryOption newSelectExpand = new SelectExpandQueryOption( SelectExpand.RawSelect, SelectExpand.RawExpand, SelectExpand.Context, processedClause); Request.ODataProperties().SelectExpandClause = processedClause; result = newSelectExpand.ApplyTo(result, querySettings); } if (querySettings.PageSize.HasValue) { bool resultsLimited; result = LimitResults(result, querySettings.PageSize.Value, out resultsLimited); if (resultsLimited && Request.RequestUri != null && Request.RequestUri.IsAbsoluteUri && Request.ODataProperties().NextLink == null) { Uri nextPageLink = GetNextPageLink(Request, querySettings.PageSize.Value); Request.ODataProperties().NextLink = nextPageLink; } } return(result); }