コード例 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataQueryOptions"/> class based on the incoming request and some metadata information from 
        /// the <see cref="ODataQueryContext"/>.
        /// </summary>
        /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information</param>
        /// <param name="request">The incoming request message</param>
        public ODataQueryOptions(ODataQueryContext context, HttpRequestMessage request)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            // remember the context
            Context = context;

            // Parse the query from request Uri
            RawValues = new ODataRawQueryOptions();
            IEnumerable<KeyValuePair<string, string>> queryParameters = request.GetQueryNameValuePairs();
            foreach (KeyValuePair<string, string> kvp in queryParameters)
            {
                switch (kvp.Key)
                {
                    case "$filter":
                        RawValues.Filter = kvp.Value;
                        ThrowIfEmpty(kvp.Value, "$filter");
                        Filter = new FilterQueryOption(kvp.Value, context);
                        break;
                    case "$orderby":
                        RawValues.OrderBy = kvp.Value;
                        ThrowIfEmpty(kvp.Value, "$orderby");
                        OrderBy = new OrderByQueryOption(kvp.Value, context);
                        break;
                    case "$top":
                        RawValues.Top = kvp.Value;
                        ThrowIfEmpty(kvp.Value, "$top");
                        Top = new TopQueryOption(kvp.Value, context);
                        break;
                    case "$skip":
                        RawValues.Skip = kvp.Value;
                        ThrowIfEmpty(kvp.Value, "$skip");
                        Skip = new SkipQueryOption(kvp.Value, context);
                        break;
                    case "$select":
                        RawValues.Select = kvp.Value;
                        break;
                    case "$inlinecount":
                        RawValues.InlineCount = kvp.Value;
                        break;
                    case "$expand":
                        RawValues.Expand = kvp.Value;
                        break;
                    case "$skiptoken":
                        RawValues.SkipToken = kvp.Value;
                        break;
                    default:
                        // we don't throw if we can't recognize the query
                        break;
                }
            }
        }
コード例 #2
0
        public void Value_Returns_ParsedTopValue(string topValue, int expectedValue)
        {
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel();
            var context = new ODataQueryContext(model, typeof(Customer));
            var top = new TopQueryOption(topValue, context);

            Assert.Equal(expectedValue, top.Value);
        }
コード例 #3
0
        public void ApplyInvalidSkipQueryThrows(string topValue)
        {
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel();
            var context = new ODataQueryContext(model, typeof(Customer));
            var top = new TopQueryOption(topValue, context);

            Assert.Throws<ODataException>(() =>
                top.ApplyTo(ODataQueryOptionTest.Customers, new ODataQuerySettings()));
        }
コード例 #4
0
        private static IQuery Apply(this IQuery query, TopQueryOption topQuery)
        {
            if (topQuery != null)
            {
                query = query.SetMaxResults(topQuery.Value);
            }

            return query;
        }
コード例 #5
0
        public void CanConstructValidFilterQuery(string topValue)
        {
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel();
            var context = new ODataQueryContext(model, typeof(Customer));
            var top = new TopQueryOption(topValue, context);

            Assert.Same(context, top.Context);
            Assert.Equal(topValue, top.RawValue);
        }
コード例 #6
0
        public void ApplyTo_WithUnTypedContext_Throws_InvalidOperation()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataQueryContext context = new ODataQueryContext(model.Model, model.Customer);
            TopQueryOption top = new TopQueryOption("42", context);
            IQueryable queryable = new Mock<IQueryable>().Object;

            // Act & Assert
            Assert.Throws<NotSupportedException>(() => top.ApplyTo(queryable, new ODataQuerySettings()),
                "The query option is not bound to any CLR type. 'ApplyTo' is only supported with a query option bound to a CLR type.");
        }
コード例 #7
0
ファイル: ODataHelper.cs プロジェクト: alexlapinski/autohaus
        public static HttpRequestMessage BuildCustomRequest(this ODataQueryOptions originalOptions,
            out TopQueryOption top,
            out SkipQueryOption skip, out OrderByQueryOption orderBy)
        {
            top = null;
            skip = null;
            orderBy = null;

            // cuttin out $top and $skip from the request
            HttpRequestMessage customRequest = originalOptions.Request;

            if (customRequest.Properties.ContainsKey(HttpPropertyKeys.RequestQueryNameValuePairsKey))
            {
                Uri uri = originalOptions.Request.RequestUri;
                var pairs =
                    customRequest.Properties[HttpPropertyKeys.RequestQueryNameValuePairsKey] as
                        IEnumerable<KeyValuePair<string, string>>;

                if (pairs != null)
                {
                    IEnumerable<KeyValuePair<string, string>> jQueryNameValuePairs =
                        new FormDataCollection(uri).GetJQueryNameValuePairs();
                    var updatedPairs = new List<KeyValuePair<string, string>>();

                    foreach (var pair in jQueryNameValuePairs)
                    {
                        if (pair.Key.Equals("$top"))
                        {
                            top = originalOptions.Top;
                        }
                        else if (pair.Key.Equals("$skip"))
                        {
                            skip = originalOptions.Skip;
                        }
                        else if (pair.Key.Equals("$orderby"))
                        {
                            orderBy = originalOptions.OrderBy;
                        }
                        else
                        {
                            updatedPairs.Add(pair);
                        }
                    }

                    customRequest.Properties.Remove(HttpPropertyKeys.RequestQueryNameValuePairsKey);
                    customRequest.Properties.Add(HttpPropertyKeys.RequestQueryNameValuePairsKey, updatedPairs);
                }
            }

            return customRequest;
        }
コード例 #8
0
        public void CanApplyTop()
        {
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel();
            var topOption = new TopQueryOption("1", new ODataQueryContext(model, typeof(Customer), "Customers"));

            var customers = (new List<Customer>{
                new Customer { CustomerId = 1, Name = "Andy" },
                new Customer { CustomerId = 2, Name = "Aaron" },
                new Customer { CustomerId = 3, Name = "Alex" }
            }).AsQueryable();

            var results = topOption.ApplyTo(customers).ToArray();
            Assert.Equal(1, results.Length);
            Assert.Equal(1, results[0].CustomerId);
        }
コード例 #9
0
        /// <summary>
        /// Validates a <see cref="TopQueryOption" />.
        /// </summary>
        /// <param name="topQueryOption">The $top query.</param>
        /// <param name="validationSettings">The validation settings.</param>
        public virtual void Validate(TopQueryOption topQueryOption, ODataValidationSettings validationSettings)
        {
            if (topQueryOption == null)
            {
                throw Error.ArgumentNull("topQueryOption");
            }

            if (validationSettings == null)
            {
                throw Error.ArgumentNull("validationSettings");
            }

            if (topQueryOption.Value > validationSettings.MaxTop)
            {
                throw new ODataException(Error.Format(SRResources.SkipTopLimitExceeded, validationSettings.MaxTop, AllowedQueryOptions.Top, topQueryOption.Value));
            }
        }
コード例 #10
0
        /// <summary>
        /// Validates a <see cref="TopQueryOption" />.
        /// </summary>
        /// <param name="topQueryOption">The $top query.</param>
        /// <param name="validationSettings">The validation settings.</param>
        public virtual void Validate(TopQueryOption topQueryOption, ODataValidationSettings validationSettings)
        {
            if (topQueryOption == null)
            {
                throw Error.ArgumentNull("topQueryOption");
            }

            if (validationSettings == null)
            {
                throw Error.ArgumentNull("validationSettings");
            }

            if (topQueryOption.Value > validationSettings.MaxTop)
            {
                throw new ODataException(Error.Format(SRResources.SkipTopLimitExceeded, validationSettings.MaxTop, AllowedQueryOptions.Top, topQueryOption.Value));
            }
        }
コード例 #11
0
        private string BuildSkipTopClause(TopQueryOption topQueryOption, SkipQueryOption skipQueryOption)
        {
            string skipTopClause = string.Empty;

            if (topQueryOption != null)
            {
                int skipValue = skipQueryOption?.Value ?? 0;
                skipTopClause = $"OFFSET {skipValue} ROWS FETCH NEXT {topQueryOption.Value} ROWS ONLY";
            }

            if (topQueryOption == null && skipQueryOption != null)
            {
                skipTopClause = $"OFFSET {skipQueryOption.Value} ROWS";
            }

            return(skipTopClause);
        }
コード例 #12
0
        public ODataQueryOptions(IEnumerable <KeyValuePair <string, string> > queryParameters, ODataQueryContext context, bool aggregate)
        {
            if (queryParameters == null)
            {
                throw new ArgumentNullException(nameof(queryParameters));
            }

            foreach (var queryParameter in queryParameters)
            {
                switch (queryParameter.Key)
                {
                case "$filter":
                    if (!aggregate)
                    {
                        Filter = new FilterQueryOption(queryParameter.Value, context);
                    }
                    break;

                case "$orderby":
                    OrderBy = new OrderByQueryOption(queryParameter.Value, context);
                    break;

                case "$select":
                    if (aggregate)
                    {
                        Select = new SelectExpandQueryOption(queryParameter.Value, string.Empty, context);
                    }
                    break;

                case "$top":
                    Top = new TopQueryOption(queryParameter.Value, context);
                    break;

                case "$format":
                    break;

                default:
                    throw new ArgumentException($"'{queryParameter.Key}' option is not supported");
                }
            }
        }
コード例 #13
0
        public void CanApplySkipTopOrderby()
        {
            var model   = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel();
            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockContainer()
            };
            var orderbyOption = new OrderByQueryOption("Name", context);
            var skipOption    = new SkipQueryOption("2", context);
            var topOption     = new TopQueryOption("2", context);

            var customers = (new List <Customer> {
                new Customer {
                    CustomerId = 1, Name = "Andy"
                },
                new Customer {
                    CustomerId = 2, Name = "Aaron"
                },
                new Customer {
                    CustomerId = 3, Name = "Alex"
                },
                new Customer {
                    CustomerId = 4, Name = "Ace"
                },
                new Customer {
                    CustomerId = 5, Name = "Abner"
                }
            }).AsQueryable();

            IQueryable queryable = orderbyOption.ApplyTo(customers);

            queryable = skipOption.ApplyTo(queryable, new ODataQuerySettings());
            queryable = topOption.ApplyTo(queryable, new ODataQuerySettings());
            var results = ((IQueryable <Customer>)queryable).ToArray();

            Assert.Equal(2, results.Length);
            Assert.Equal(4, results[0].CustomerId);
            Assert.Equal(3, results[1].CustomerId);
        }
コード例 #14
0
        public void CanApplyTop()
        {
            var model     = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel();
            var topOption = new TopQueryOption("1", new ODataQueryContext(model, typeof(Customer)));

            var customers = (new List <Customer> {
                new Customer {
                    CustomerId = 1, Name = "Andy"
                },
                new Customer {
                    CustomerId = 2, Name = "Aaron"
                },
                new Customer {
                    CustomerId = 3, Name = "Alex"
                }
            }).AsQueryable();

            var results = topOption.ApplyTo(customers, new ODataQuerySettings()).ToArray();

            Assert.Single(results);
            Assert.Equal(1, results[0].CustomerId);
        }
コード例 #15
0
        public void CanApplySkipTopOrderby()
        {
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel();
            var context = new ODataQueryContext(model, typeof(Customer));
            var orderbyOption = new OrderByQueryOption("Name", context, queryTranslator: null);
            var skipOption = new SkipQueryOption("2", context);
            var topOption = new TopQueryOption("2", context);

            var customers = (new List<Customer>{
                new Customer { CustomerId = 1, Name = "Andy" },
                new Customer { CustomerId = 2, Name = "Aaron" },
                new Customer { CustomerId = 3, Name = "Alex" },
                new Customer { CustomerId = 4, Name = "Ace" },
                new Customer { CustomerId = 5, Name = "Abner" }
            }).AsQueryable();

            IQueryable queryable = orderbyOption.ApplyTo(customers);
            queryable = skipOption.ApplyTo(queryable, new ODataQuerySettings());
            queryable = topOption.ApplyTo(queryable, new ODataQuerySettings());
            var results = ((IQueryable<Customer>)queryable).ToArray();
            Assert.Equal(2, results.Length);
            Assert.Equal(4, results[0].CustomerId);
            Assert.Equal(3, results[1].CustomerId);
        }
コード例 #16
0
        public void Property_Value_WorksWithUnTypedContext()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataQueryContext context = new ODataQueryContext(model.Model, model.Customer);
            TopQueryOption top = new TopQueryOption("42", context);

            // Act & Assert
            Assert.Equal(42, top.Value);
        }
コード例 #17
0
 public static IAsyncEnumerable <T> ApplyTo <T>(this TopQueryOption query, IAsyncEnumerable <T> source, ODataQuerySettings settings)
 {
     return(source.TakeAsync(query.Value));
 }
コード例 #18
0
        /// <summary>
        /// Updates the QueryExpression's paging settings based on OData parameters.
        /// </summary>
        /// <param name="pagingInfo">The target PagingInfo</param>
        /// <param name="skip">The OData options that describe how many records to skip.</param>
        /// <param name="top">The OData options that describe how many records per page.</param>
        private static void UpdatePagingFromSkipAndTop(PagingInfo pagingInfo, SkipQueryOption skip, TopQueryOption top)
        {
            if (top == null)
            {
                pagingInfo.Count = 50;
            }
            else
            {
                pagingInfo.Count = top.Value;
            }

            if (skip == null)
            {
                pagingInfo.PageNumber = 1;
            }
            else
            {
                // When syncing for offline, the client will always request a page immediately after
                // the last record.  So if there are only 7 records, it will request with $top=50 and
                // $skip=7.  To handle these cases when $skip is not evenly divisible by $top, we round
                // up, which will send back an empty result set on the last page and complete the sync.
                pagingInfo.PageNumber = (int)Math.Ceiling((double)skip.Value / pagingInfo.Count) + 1;
            }
        }
コード例 #19
0
        private string BuildOrderClause(EdmEntityType edmEntityType, OrderByQueryOption orderByQueryOption, TopQueryOption topQueryOption, SkipQueryOption skipQueryOption)
        {
            string orderClause   = BuildOrderClause(edmEntityType, orderByQueryOption);
            string skipTopClause = BuildSkipTopClause(topQueryOption, skipQueryOption);

            if (string.IsNullOrEmpty(skipTopClause))
            {
                return(orderClause);
            }

            return($"{orderClause} {skipTopClause}");
        }
コード例 #20
0
ファイル: AboutOData.cs プロジェクト: sara62/WebApiKoans
 private static bool ValidateTopQueryOption(TopQueryOption top)
 {
     if (top != null && top.RawValue != null)
     {
         int topValue = Int32.Parse(top.RawValue, NumberStyles.None);
         return topValue < 10;
     }
     return true;
 }
コード例 #21
0
        private Task <IEnumerable <PackageName> > Query(FeedPrincipal principal, string packageNamePrefix, SkipQueryOption skip, TopQueryOption top)
        {
            var feed = storage.GetFeed(principal.FeedName);

            switch (principal.AuthenticatedArea)
            {
            case AuthenticatedArea.QueryingOwn:
                return(skip != null && top != null
                        ? feed.QueryPackages(principal.Identity.Name, principal.PackageState, packageNamePrefix, skip.Value, top.Value)
                        : feed.QueryPackages(principal.Identity.Name, principal.PackageState));

            case AuthenticatedArea.QueryingAll:
                return(skip != null && top != null
                        ? feed.QueryPackages(principal.PackageState, packageNamePrefix, skip.Value, top.Value)
                        : feed.QueryPackages(principal.PackageState));

            default:
                throw new ArgumentOutOfRangeException("area", principal.AuthenticatedArea, null);
            }
        }
コード例 #22
0
        public void Value_ThrowsODataException_ForInvalidValues(string skipValue)
        {
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel();
            var context = new ODataQueryContext(model, typeof(Customer));
            var top = new TopQueryOption(skipValue, context);

            Assert.Throws<ODataException>(() => top.Value);
        }
コード例 #23
0
        public void CanTurnOffValidationForTop()
        {
            // Arrange
            ODataValidationSettings settings = new ODataValidationSettings()
            {
                MaxTop = 10
            };
            TopQueryOption option = new TopQueryOption("11", ValidationTestHelper.CreateCustomerContext());

            // Act and Assert
            Assert.Throws<ODataException>(() =>
                option.Validate(settings),
                "The limit of '10' for Top query has been exceeded. The value from the incoming request is '11'.");
            option.Validator = null;
            Assert.DoesNotThrow(() => option.Validate(settings));
        }