public ODataQuerySettings GetODataQuerySettings() { var settings = new ODataQuerySettings() { EnableConstantParameterization = this.EnableConstantParameterization, EnsureStableOrdering = this.EnsureStableOrdering, HandleNullPropagation = this.HandleNullPropagation, PageSize = this.PageSize > 0 ? this.PageSize : (int?)null }; return settings; }
public void Ctor_Initializes_All_Properties() { // Arrange & Act ODataQuerySettings querySettings = new ODataQuerySettings(); // Assert Assert.Equal(HandleNullPropagationOption.Default, querySettings.HandleNullPropagation); Assert.True(querySettings.EnsureStableOrdering); }
public PageResult<Order> GetOrders(ODataQueryOptions<Order> options) { var settings = new ODataQuerySettings(); var fromDatabase = _context.Orders.Where(order => order.Freight != 123); var results = options.ApplyTo(fromDatabase.AsQueryable(), settings); return new PageResult<Order>( results as IQueryable<Order>, Request.ODataProperties().NextLink, Request.ODataProperties().TotalCount); }
public void GetResultSize_ReturnsEffectivePageSize(string top, int? pageSize, int expected) { // Arrange ODataQueryContext context = new ODataQueryContext(EdmModelMock.Create<Movie>("Movies"), typeof(Movie)); Uri address = new Uri("http://localhost?{0}".FormatInvariant(top)); ODataQueryOptions query = new ODataQueryOptions(context, new HttpRequestMessage { RequestUri = address }); ODataQuerySettings settings = new ODataQuerySettings() { PageSize = pageSize }; // Act int actual = TableUtils.GetResultSize(query, settings); // Assert Assert.Equal(expected, actual); }
public PageResult<ArticleDto> Get(ODataQueryOptions<ArticleDto> options) { var settings = new ODataQuerySettings { PageSize = 10, EnsureStableOrdering = false }; var artikelQuery = productsContext.Articles .OrderBy(a => a.Id).AsNoTracking().Project().To<ArticleDto>(null, dest => dest.Id, dest => dest.Name, dest => dest.Code); var results = options.ApplyTo(artikelQuery, settings); return new PageResult<ArticleDto>( results as IEnumerable<ArticleDto>, Request.ODataProperties().NextLink, Request.ODataProperties().TotalCount); }
public void ApplyTo_NestedProperties_DoesNotHandleNullPropagation_IfExplicitInSettings() { // Arrange var model = new ODataModelBuilder().Add_Customer_EntityType_With_Address().Add_Customers_EntitySet().GetServiceModel(); var orderByOption = new OrderByQueryOption("Address/City asc", new ODataQueryContext(model, typeof(Customer)), null); var customers = (new List<Customer>{ new Customer { CustomerId = 1, Address = null }, new Customer { CustomerId = 2, Address = new Address { City = "B" } }, new Customer { CustomerId = 3, Address = new Address { City = "A" } } }).AsQueryable(); ODataQuerySettings settings = new ODataQuerySettings { HandleNullPropagation = HandleNullPropagationOption.False }; // Act & Assert Assert.Throws<NullReferenceException>(() => orderByOption.ApplyTo(customers, settings).ToArray()); }
internal static int GetCount(ODataQueryOptions<VELEMIMUNKAINMLIST> queryOptions) { using (MIRTUSZContext.MIRTUSZDataContext mirtuszDC = new MIRTUSZContext.MIRTUSZDataContext()) { mirtuszDC.Connection.Open(); if (queryOptions.Filter != null) { ODataQuerySettings settings = new ODataQuerySettings() { PageSize = 1000000 }; IQueryable query = queryOptions.ApplyTo(mirtuszDC.VELEMIMUNKAINMLISTs, settings); return query.Cast<VELEMIMUNKAINMLIST>().Count(); } return mirtuszDC.VELEMIMUNKAINMLISTs.Count(); } }
public PageResult<ViewTradeResource> Get([FromUri] FilterOptions filterOptions, ODataQueryOptions queryOptions) { var querySettings = new ODataQuerySettings { PageSize = 20 }; var data = _tradeRepository .Get(filterOptions.BasketName); var results = queryOptions.ApplyTo(_mappingEngine.Map<IEnumerable<Trade>, IEnumerable<ViewTradeResource>>(data).AsQueryable(), querySettings) .Cast<ViewTradeResource>(); return new PageResult<ViewTradeResource>( results, Request.GetNextPageLink(), Request.GetInlineCount() ); }
public PageResult<Customer> Get(ODataQueryOptions<Customer> options) { Guid VALID_TENANT_ID = Guid.Parse("7b6791d5-8658-44e5-86bc-8181735d0bf7"); IQueryable query = dbContext.Customers.Where(c => c.Tenant_Id == VALID_TENANT_ID); ODataQuerySettings odataSettings = new ODataQuerySettings(); if (options.Filter != null) { // set validator that restricts client's filtering options.Filter.Validator = new QuoteQueryValidator(); options.Validate(new ODataValidationSettings()); query = options.Filter.ApplyTo(query, odataSettings); } // get the total count IQueryable<Customer> custQuery = query as IQueryable<Customer>; long totalCount = custQuery.LongCount(); if (options.OrderBy != null) { query = options.OrderBy.ApplyTo(query, odataSettings); } if (options.Skip != null) query = options.Skip.ApplyTo(query, odataSettings); if (options.Top != null) query = options.Top.ApplyTo(query, odataSettings); // if (options.SelectExpand != null) // query = options.SelectExpand.ApplyTo(query, odataSettings); //var resultList = new List<Customer>(query); var retValue = new PageResult<Customer>( query as IEnumerable<Customer>, Request.GetNextPageLink(), totalCount); return retValue; }
public PageResult<Vessel> Get(ODataQueryOptions<Vessel> options) { // Implementation from here: // http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options // TODO May want to limit additional query options ODataQuerySettings settings = new ODataQuerySettings() { PageSize = 15 }; var repo = TubsDataService.GetRepository<Vessel>(MvcApplication.CurrentSession); IQueryable results = options.ApplyTo(repo.All(), settings); // Not sure how to get the appropriate count // what is wanted is repo.All().Where(???).Count(); return new PageResult<Vessel>( results as IEnumerable<Vessel>, Request.GetNextPageLink(), Request.GetInlineCount() ); }
public PageResult<BasketResource> Get([FromUri]FilterOptions options, ODataQueryOptions queryOptions) { var querySettings = new ODataQuerySettings { PageSize = 20 }; var data = _basketRepository .Get(options.QuoteId, options.BrokerName, options.CustomerName, options.BasketName) .Project() .To<BasketResource>() .Take(500); //return data; var results = queryOptions.ApplyTo(data, querySettings) .Cast<BasketResource>(); return new PageResult<BasketResource>( results, Request.GetNextPageLink(), Request.GetInlineCount() ); }
public PageResult<BrokerResource> Get([FromUri]FilterOptions options, ODataQueryOptions queryOptions) { var querySettings = new ODataQuerySettings {PageSize = 20}; var data = _brokerRepository .Get(options.QuoteId, options.BrokerName, null, //new long[] { 1234, 4321 }, options.BasketName) .Project() .To<BrokerResource>() .Where(b => !options.Active.HasValue || b.Active == options.Active.Value) .Take(500); //return data; var results = queryOptions.ApplyTo(data, querySettings) .Cast<BrokerResource>(); return new PageResult<BrokerResource>( results, Request.GetNextPageLink(), Request.GetInlineCount() ); }
public PageResult<CustomerResource> Get([FromUri]FilterOptions options, ODataQueryOptions queryOptions) { var querySettings = new ODataQuerySettings { PageSize = 20 }; //var svc = new PcdsServiceClient(); //var data = svc.GetGroupDetails(options.CustomerName) var data = GetCustomers() .Where(c => (options.CustomerName == null) || (options.CustomerName != null) && c.CustomerName.Contains(options.CustomerName)) //.Select(d => new CustomerResource { CustomerName = d.Details.GROUP_NAME, NumberOfSites = d.SiteCount, Id = (int)d.Details.ID, CustomerId = "C" + d.Details.ID.ToString()}) .AsQueryable() .Take(500); //.Project() //.To<CustomerResource>(); //return data; var results = queryOptions.ApplyTo(data, querySettings) .Cast<CustomerResource>(); return new PageResult<CustomerResource>( results, Request.GetNextPageLink(), Request.GetInlineCount() ); }
public IQueryable ApplyTo(IQueryable queryable, ODataQuerySettings settings) { if (queryable == null) { throw Error.ArgumentNull("queryable"); } if (settings == null) { throw Error.ArgumentNull("settings"); } // Ensure we have decided how to handle null propagation ODataQuerySettings updatedSettings = settings; if (settings.HandleNullPropagation == HandleNullPropagationOption.Default) { updatedSettings = new ODataQuerySettings(updatedSettings); updatedSettings.HandleNullPropagation = HandleNullPropagationOptionHelper.GetDefaultHandleNullPropagationOption(queryable); } return SelectExpandBinder.Bind(queryable, updatedSettings, this); }
/// <summary> /// Applies the $select and $expand query options to the given entity using the given <see cref="ODataQuerySettings"/>. /// </summary> /// <param name="entity">The original entity.</param> /// <param name="settings">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> public object ApplyTo(object entity, ODataQuerySettings settings) { if (entity == null) { throw Error.ArgumentNull("entity"); } if (settings == null) { throw Error.ArgumentNull("settings"); } // Ensure we have decided how to handle null propagation ODataQuerySettings updatedSettings = settings; if (settings.HandleNullPropagation == HandleNullPropagationOption.Default) { updatedSettings = new ODataQuerySettings(updatedSettings); updatedSettings.HandleNullPropagation = HandleNullPropagationOption.True; } return SelectExpandBinder.Bind(entity, updatedSettings, this); }
/// <summary> /// Apply the filter query to the given IQueryable. /// </summary> /// <remarks> /// The <see cref="ODataQuerySettings.HandleNullPropagation"/> property specifies /// how this method should handle null propagation. /// </remarks> /// <param name="query">The IQueryable that we are applying filter query against.</param> /// <param name="querySettings">Specifies if we need to handle null propagation. Pass false if the underlying query provider handles null propagation. Otherwise pass true.</param> /// <param name="assembliesResolver">The <see cref="IAssembliesResolver"/> to use.</param> /// <returns>The query that the filter query has been applied to.</returns> public IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings, IAssembliesResolver assembliesResolver) { if (query == null) { throw Error.ArgumentNull("query"); } if (querySettings == null) { throw Error.ArgumentNull("querySettings"); } if (assembliesResolver == null) { throw Error.ArgumentNull("assembliesResolver"); } FilterQueryNode node = QueryNode; Contract.Assert(node != null); Expression filter = FilterBinder.Bind(node, Context.EntityClrType, Context.Model, assembliesResolver, querySettings); query = ExpressionHelpers.Where(query, filter, Context.EntityClrType); return query; }
public void ApplyTo_Adds_Missing_Keys_To_OrderBy(string oDataQuery, bool ensureStableOrdering, string expectedExpression) { // Arrange var model = new ODataModelBuilder() .Add_Customers_With_Keys_EntitySet(c => new { c.CustomerId, c.Name }).GetEdmModel(); var message = new HttpRequestMessage( HttpMethod.Get, new Uri("http://server/service/Customers?" + oDataQuery) ); var queryOptions = new ODataQueryOptions(new ODataQueryContext(model, typeof(Customer), "Customers"), message); ODataQuerySettings querySettings = new ODataQuerySettings { EnsureStableOrdering = ensureStableOrdering, }; // Act IQueryable finalQuery = queryOptions.ApplyTo(new Customer[0].AsQueryable(), querySettings); // Assert string queryExpression = finalQuery.Expression.ToString(); queryExpression = queryExpression.Substring(queryExpression.IndexOf("]") + 2); Assert.Equal(queryExpression, expectedExpression); }
public QueryableAttribute(bool handleNullPropagation = false) { this.querySettings = new ODataQuerySettings(); }
/// <summary> /// Apply the individual query to the given IQueryable in the right order. /// </summary> /// <param name="query">The IQueryable that we are applying query against.</param> /// <param name="querySettings">The settings to use in query composition.</param> /// <returns>The query that the query has been applied to.</returns> public IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings) { if (query == null) { throw Error.ArgumentNull("query"); } if (querySettings == null) { throw Error.ArgumentNull("querySettings"); } // Ensure we have decided how to handle null propagation if (querySettings.HandleNullPropagation == HandleNullPropagationOption.Default) { querySettings.HandleNullPropagation = GetDefaultHandleNullPropagationOption(query); } 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); } OrderByQueryOption orderBy = OrderBy; // $skip or $top require a stable sort for predictable results. // If either is present in the query and we have permission, // generate an $orderby that will produce a stable sort. if ((Skip != null || Top != null) && querySettings.EnsureStableOrdering && !Context.IsPrimitiveClrType) { // 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); } if (Skip != null) { result = Skip.ApplyTo(result); } if (Top != null) { result = Top.ApplyTo(result); } return result; }
// demo 2: low level APIs public IQueryable<QueryCompositionCustomer> Get(ODataQueryOptions queryOptions) { if (!ModelState.IsValid) { throw new HttpResponseException(HttpStatusCode.BadRequest); } IQueryable<QueryCompositionCustomer> result = null; try { ODataQuerySettings querySettings = new ODataQuerySettings { EnsureStableOrdering = false }; result = queryOptions.ApplyTo(QueryCompositionCustomerController.CustomerList.AsQueryable(), querySettings) as IQueryable<QueryCompositionCustomer>; } catch (ODataException exception) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, exception)); } return result; }
public void ApplyTo_Builds_Default_OrderBy_No_Keys(string oDataQuery, bool ensureStableOrdering, string expectedExpression) { var model = new ODataModelBuilder().Add_Customer_No_Keys_EntityType().Add_Customers_No_Keys_EntitySet().GetEdmModel(); var message = new HttpRequestMessage( HttpMethod.Get, new Uri("http://server/service/Customers?" + oDataQuery) ); var options = new ODataQueryOptions(new ODataQueryContext(model, typeof(Customer), "Customers"), message); ODataQuerySettings querySettings = new ODataQuerySettings { EnsureStableOrdering = ensureStableOrdering }; IQueryable finalQuery = options.ApplyTo(new Customer[0].AsQueryable(), querySettings); string queryExpression = finalQuery.Expression.ToString(); queryExpression = queryExpression.Substring(queryExpression.IndexOf("]") + 2); Assert.Equal(queryExpression, expectedExpression); }
public static Uri GetNextLink(Uri currentRequestUri, long? totalResultCount, object queryParameters, ODataQueryOptions options, ODataQuerySettings settings) { if (!totalResultCount.HasValue || totalResultCount.Value <= MaxPageSize || totalResultCount.Value == 0) { return null; // no need for a next link if there are no additional results on this page } var skipCount = (options.Skip != null ? options.Skip.Value : 0) + Math.Min(totalResultCount.Value, (settings.PageSize != null ? settings.PageSize.Value : SearchAdaptor.MaxPageSize)); if (totalResultCount.Value <= skipCount) { return null; // no need for a next link if there are no additional results in the result set } var queryBuilder = new StringBuilder(); var queryParametersCollection = new RouteValueDictionary(queryParameters); foreach (var queryParameter in queryParametersCollection) { queryBuilder.Append(Uri.EscapeDataString(queryParameter.Key)); queryBuilder.Append("="); if (queryParameter.Value != null) { if (queryParameter.Value is string) { queryBuilder.Append(Uri.EscapeDataString("'" + queryParameter.Value + "'")); } else if (queryParameter.Value is bool) { queryBuilder.Append(queryParameter.Value.ToString().ToLowerInvariant()); } else { queryBuilder.Append(queryParameter.Value.ToString().ToLowerInvariant()); } } queryBuilder.Append("&"); } if (options.SelectExpand != null) { if (!string.IsNullOrEmpty(options.SelectExpand.RawSelect)) { queryBuilder.Append("$select="); queryBuilder.Append(options.SelectExpand.RawSelect); queryBuilder.Append("&"); } if (!string.IsNullOrEmpty(options.SelectExpand.RawExpand)) { queryBuilder.Append("$expand="); queryBuilder.Append(options.SelectExpand.RawExpand); queryBuilder.Append("&"); } } if (options.Filter != null) { queryBuilder.Append("$filter="); queryBuilder.Append(options.Filter.RawValue); queryBuilder.Append("&"); } if (options.OrderBy != null) { queryBuilder.Append("$orderby="); queryBuilder.Append(options.OrderBy.RawValue); queryBuilder.Append("&"); } if (skipCount > 0) { queryBuilder.Append("$skip="); queryBuilder.Append(skipCount); queryBuilder.Append("&"); } if (options.Top != null) { queryBuilder.Append("$top="); queryBuilder.Append(options.Top.RawValue); queryBuilder.Append("&"); } var queryString = queryBuilder.ToString().TrimEnd('&'); var builder = new UriBuilder(currentRequestUri); builder.Query = queryString; return builder.Uri; }
private IQueryable ApplyToCore(IQueryable query, ODataQuerySettings querySettings) { return(ExpressionHelpers.Take(query, Value, Context.ElementClrType, querySettings.EnableConstantParameterization)); }
/// <summary> /// Apply the filter query to the given IQueryable. /// </summary> /// <remarks> /// The <see cref="ODataQuerySettings.HandleNullPropagation"/> property specifies /// how this method should handle null propagation. /// </remarks> /// <param name="query">The original <see cref="IQueryable"/>.</param> /// <param name="querySettings">The <see cref="ODataQuerySettings"/> that contains all the query application related settings.</param> /// <returns>The new <see cref="IQueryable"/> after the filter query has been applied to.</returns> public IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings) { return(ApplyTo(query, querySettings, _defaultAssembliesResolver)); }
/// <summary> /// Apply the filter query to the given IQueryable. /// </summary> /// <remarks> /// The <see cref="ODataQuerySettings.HandleNullPropagation"/> property specifies /// how this method should handle null propagation. /// </remarks> /// <param name="query">The original <see cref="IQueryable"/>.</param> /// <param name="querySettings">The <see cref="ODataQuerySettings"/> that contains all the query application related settings.</param> /// <param name="assembliesResolver">The <see cref="IAssembliesResolver"/> to use.</param> /// <returns>The new <see cref="IQueryable"/> after the filter query has been applied to.</returns> public IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings, IAssembliesResolver assembliesResolver) { if (query == null) { throw Error.ArgumentNull("query"); } if (querySettings == null) { throw Error.ArgumentNull("querySettings"); } if (assembliesResolver == null) { throw Error.ArgumentNull("assembliesResolver"); } if (Context.ElementClrType == null) { throw Error.NotSupported(SRResources.ApplyToOnUntypedQueryOption, "ApplyTo"); } FilterClause filterClause = FilterClause; Contract.Assert(filterClause != null); // Ensure we have decided how to handle null propagation ODataQuerySettings updatedSettings = querySettings; if (querySettings.HandleNullPropagation == HandleNullPropagationOption.Default) { updatedSettings = new ODataQuerySettings(updatedSettings); updatedSettings.HandleNullPropagation = HandleNullPropagationOptionHelper.GetDefaultHandleNullPropagationOption(query); } Expression filter = FilterBinder.Bind(filterClause, Context.ElementClrType, Context.Model, assembliesResolver, updatedSettings); query = ExpressionHelpers.Where(query, filter, Context.ElementClrType); return query; }
public PageResult<Product> GetProducts(ODataQueryOptions<Product> options) { var settings = new ODataQuerySettings() { PageSize = 1 }; if (options.OrderBy != null) { options.OrderBy.Validator = new MyOrderByValidator(); } var settingsVal = new ODataValidationSettings() { // Initialize settings as needed. AllowedFunctions = AllowedFunctions.AllMathFunctions }; // Validate options.Validate(settingsVal); IQueryable results = options.ApplyTo(Repository.GetAll().Select(AsProductTo), settings); return new PageResult<Product>( results as IEnumerable<Product>, Request.GetNextPageLink(), Request.GetInlineCount()); }
/// <summary> /// Apply the filter query to the given IQueryable. /// </summary> /// <remarks> /// The <see cref="ODataQuerySettings.HandleNullPropagation"/> property specifies /// how this method should handle null propagation. /// </remarks> /// <param name="query">The original <see cref="IQueryable"/>.</param> /// <param name="querySettings">The <see cref="ODataQuerySettings"/> that contains all the query application related settings.</param> /// <returns>The new <see cref="IQueryable"/> after the filter query has been applied to.</returns> public IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings) { return ApplyTo(query, querySettings, _defaultAssembliesResolver); }
/// <summary> /// Apply the $orderby query to the given IQueryable. /// </summary> /// <param name="query">The original <see cref="IQueryable"/>.</param> /// <param name="querySettings">The <see cref="ODataQuerySettings"/> that contains all the query application related settings.</param> /// <returns>The new <see cref="IQueryable"/> after the orderby query has been applied to.</returns> public IOrderedQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings) { return(ApplyToCore(query, querySettings)); }
/// <summary> /// Apply the individual query to the given IQueryable in the right order. /// </summary> /// <param name="query">The IQueryable that we are applying query against.</param> /// <param name="querySettings">The settings to use in query composition.</param> /// <returns>The query that 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"); } // Ensure we have decided how to handle null propagation if (querySettings.HandleNullPropagation == HandleNullPropagationOption.Default) { querySettings.HandleNullPropagation = GetDefaultHandleNullPropagationOption(query); } 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); } 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 && !Context.IsPrimitiveClrType && (Skip != null || Top != null || querySettings.ResultLimit.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); } if (Skip != null) { result = Skip.ApplyTo(result); } if (Top != null) { result = Top.ApplyTo(result); } if (querySettings.ResultLimit.HasValue) { bool resultsLimited; result = LimitResults(result, querySettings.ResultLimit.Value, Context, out resultsLimited); if (resultsLimited && Request.RequestUri != null && Request.RequestUri.IsAbsoluteUri) { Uri nextPageLink = GetNextPageLink(Request, querySettings.ResultLimit.Value); Request.Properties.Add(NextPageLinkPropertyKey, nextPageLink); } } return(result); }
private IOrderedQueryable ApplyToCore(IQueryable query, ODataQuerySettings querySettings) { if (Context.ElementClrType == null) { throw Error.NotSupported(SRResources.ApplyToOnUntypedQueryOption, "ApplyTo"); } ICollection <OrderByNode> nodes = OrderByNodes; bool alreadyOrdered = false; IQueryable querySoFar = query; HashSet <IEdmProperty> propertiesSoFar = new HashSet <IEdmProperty>(); bool orderByItSeen = false; foreach (OrderByNode node in nodes) { OrderByPropertyNode propertyNode = node as OrderByPropertyNode; if (propertyNode != null) { IEdmProperty property = propertyNode.Property; OrderByDirection direction = propertyNode.Direction; // This check prevents queries with duplicate properties (e.g. $orderby=Id,Id,Id,Id...) from causing stack overflows if (propertiesSoFar.Contains(property)) { throw new ODataException(Error.Format(SRResources.OrderByDuplicateProperty, property.Name)); } propertiesSoFar.Add(property); if (propertyNode.OrderByClause != null) { // Ensure we have decided how to handle null propagation ODataQuerySettings updatedSettings = querySettings; if (querySettings.HandleNullPropagation == HandleNullPropagationOption.Default) { updatedSettings = new ODataQuerySettings(updatedSettings); updatedSettings.HandleNullPropagation = HandleNullPropagationOptionHelper.GetDefaultHandleNullPropagationOption(query); } LambdaExpression orderByExpression = FilterBinder.Bind(propertyNode.OrderByClause, Context.ElementClrType, Context.Model, updatedSettings); querySoFar = ExpressionHelpers.OrderBy(querySoFar, orderByExpression, direction, Context.ElementClrType, alreadyOrdered); } else { querySoFar = ExpressionHelpers.OrderByProperty(querySoFar, property, direction, Context.ElementClrType, alreadyOrdered); } alreadyOrdered = true; } else { // This check prevents queries with duplicate nodes (e.g. $orderby=$it,$it,$it,$it...) from causing stack overflows if (orderByItSeen) { throw new ODataException(Error.Format(SRResources.OrderByDuplicateIt)); } querySoFar = ExpressionHelpers.OrderByIt(querySoFar, node.Direction, Context.ElementClrType, alreadyOrdered); alreadyOrdered = true; orderByItSeen = true; } } return(querySoFar as IOrderedQueryable); }
public IQueryable ApplyTo(IQueryable queryable, ODataQuerySettings settings) { if (queryable == null) { throw Error.ArgumentNull("queryable"); } if (settings == null) { throw Error.ArgumentNull("settings"); } if (Context.ElementClrType == null) { throw Error.NotSupported(SRResources.ApplyToOnUntypedQueryOption, "ApplyTo"); } // Ensure we have decided how to handle null propagation ODataQuerySettings updatedSettings = settings; if (settings.HandleNullPropagation == HandleNullPropagationOption.Default) { updatedSettings = new ODataQuerySettings(updatedSettings); updatedSettings.HandleNullPropagation = HandleNullPropagationOptionHelper.GetDefaultHandleNullPropagationOption(queryable); } return SelectExpandBinder.Bind(queryable, updatedSettings, this); }
private IQueryable ExecuteQuery(IEnumerable query, HttpRequestMessage request, HttpConfiguration configuration, HttpActionDescriptor actionDescriptor) { Type originalQueryType = query.GetType(); Type entityClrType = TypeHelper.GetImplementedIEnumerableType(originalQueryType); if (entityClrType == null) { // The element type cannot be determined because the type of the content // is not IEnumerable<T> or IQueryable<T>. throw Error.InvalidOperation( SRResources.FailedToRetrieveTypeToBuildEdmModel, this.GetType().Name, actionDescriptor.ActionName, actionDescriptor.ControllerDescriptor.ControllerName, originalQueryType.FullName); } ODataQueryContext queryContext = CreateQueryContext(entityClrType, configuration, actionDescriptor); ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, request); ValidateQuery(request, queryOptions); // apply the query IQueryable queryable = query as IQueryable; if (queryable == null) { queryable = query.AsQueryable(); } ODataQuerySettings querySettings = new ODataQuerySettings { EnsureStableOrdering = EnsureStableOrdering, HandleNullPropagation = HandleNullPropagation, MaxAnyAllExpressionDepth = MaxAnyAllExpressionDepth, ResultLimit = _resultLimit }; return queryOptions.ApplyTo(queryable, querySettings); }
/// <summary> /// Enables a controller action to support OData query parameters. /// </summary> public QueryableAttribute() { _validationSettings = new ODataValidationSettings(); _querySettings = new ODataQuerySettings(); }
/// <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 (InlineCount != null && Request.GetInlineCount() == null) { long?count = InlineCount.GetEntityCount(result); if (count.HasValue) { Request.SetInlineCount(count.Value); } } 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); } if (Skip != null) { result = Skip.ApplyTo(result, querySettings); } if (Top != null) { result = Top.ApplyTo(result, querySettings); } if (SelectExpand != null) { Request.SetSelectExpandClause(SelectExpand.SelectExpandClause); result = SelectExpand.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.GetNextPageLink() == null) { Uri nextPageLink = GetNextPageLink(Request, querySettings.PageSize.Value); Request.SetNextPageLink(nextPageLink); } } return(result); }
public void ApplyTo_Does_Not_Replace_Original_OrderBy_With_Missing_Keys() { // Arrange var model = new ODataModelBuilder() .Add_Customers_No_Keys_EntitySet().GetEdmModel(); var message = new HttpRequestMessage( HttpMethod.Get, new Uri("http://server/service/Customers?$orderby=Name") ); // Act var queryOptions = new ODataQueryOptions(new ODataQueryContext(model, typeof(Customer), "Customers"), message); OrderByQueryOption originalOption = queryOptions.OrderBy; ODataQuerySettings querySettings = new ODataQuerySettings(); IQueryable finalQuery = queryOptions.ApplyTo(new Customer[0].AsQueryable(), querySettings); // Assert Assert.ReferenceEquals(originalOption, queryOptions.OrderBy); }
/// <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 override IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings) { ValidateQuery(query); return(base.ApplyTo(query, querySettings)); }
public NHQueryHelper(ODataQuerySettings querySettings) : base(querySettings) { }
/// <summary> /// Apply the $orderby query to the given IQueryable. /// </summary> /// <param name="query">The original <see cref="IQueryable"/>.</param> /// <param name="querySettings">The <see cref="ODataQuerySettings"/> that contains all the query application related settings.</param> /// <returns>The new <see cref="IQueryable"/> after the orderby query has been applied to.</returns> public IOrderedQueryable <T> ApplyTo <T>(IQueryable <T> query, ODataQuerySettings querySettings) { return(ApplyToCore(query, querySettings) as IOrderedQueryable <T>); }