public void CanApplyOrderByThenBy()
        {
            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,Website", context);

            var customers = (new List <Customer> {
                new Customer {
                    CustomerId = 1, Name = "ACME", Website = "http://www.acme.net"
                },
                new Customer {
                    CustomerId = 2, Name = "AAAA", Website = "http://www.aaaa.com"
                },
                new Customer {
                    CustomerId = 3, Name = "ACME", Website = "http://www.acme.com"
                }
            }).AsQueryable();

            var results = orderByOption.ApplyTo(customers).ToArray();

            Assert.Equal(2, results[0].CustomerId);
            Assert.Equal(3, results[1].CustomerId);
            Assert.Equal(1, results[2].CustomerId);
        }
        public void CanApplyOrderByQueryCaseInsensitive(string orderbyValue)
        {
            var model   = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel();
            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockContainer()
            };
            var orderby = new OrderByQueryOption(orderbyValue, context);

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

            var results = orderby.ApplyTo(customers).ToArray();

            Assert.Equal(1, results[0].CustomerId);
            Assert.Equal(2, results[1].CustomerId);
            Assert.Equal(3, results[2].CustomerId);
        }
        public void CanApplyOrderByDescending()
        {
            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 desc", context);

            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 = orderByOption.ApplyTo(customers).ToArray();

            Assert.Equal(1, results[0].CustomerId);
            Assert.Equal(3, results[1].CustomerId);
            Assert.Equal(2, results[2].CustomerId);
        }
        public void ApplyTo_NestedProperties_DoesNotHandleNullPropagation_IfExplicitInSettings()
        {
            // Arrange
            var model   = new ODataModelBuilder().Add_Customer_EntityType_With_Address().Add_Customers_EntitySet().GetServiceModel();
            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockContainer()
            };
            var orderByOption = new OrderByQueryOption("Address/City asc", context);

            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
            ExceptionAssert.Throws <NullReferenceException>(() => orderByOption.ApplyTo(customers, settings).ToArray());
        }
        public void ApplyTo_NestedProperties_HandlesNullPropagation_Succeeds()
        {
            // Arrange
            var model   = new ODataModelBuilder().Add_Customer_EntityType_With_Address().Add_Customers_EntitySet().GetServiceModel();
            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockContainer()
            };
            var orderByOption = new OrderByQueryOption("Address/City asc", context);

            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();

            // Act
            var results = orderByOption.ApplyTo(customers).ToArray();

            // Assert
            Assert.Equal(1, results[0].CustomerId);
            Assert.Equal(3, results[1].CustomerId);
            Assert.Equal(2, results[2].CustomerId);
        }
        public void ApplyTo_PropertyAliased_IfEnabled(bool modelAliasing, string propertyName)
        {
            // Arrange
            var builder = ODataConventionModelBuilderHelper.CreateWithModelAliasing(modelAliasing);

            builder.EntitySet <PropertyAlias>("PropertyAliases");
            var model = builder.GetEdmModel();

            var context = new ODataQueryContext(model, typeof(PropertyAlias))
            {
                RequestContainer = new MockContainer(model)
            };
            var orderByOption = new OrderByQueryOption(propertyName, context);
            IEnumerable <PropertyAlias> propertyAliases = FilterQueryOptionTest.PropertyAliasTestData;

            // Act
            IQueryable queryable = orderByOption.ApplyTo(propertyAliases.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IEnumerable <PropertyAlias> actualCustomers = Assert.IsAssignableFrom <IEnumerable <PropertyAlias> >(queryable);

            Assert.Equal(
                new[] { "abc", "def", "xyz" },
                actualCustomers.Select(propertyAlias => propertyAlias.FirstName));
        }
        public void ApplyToEnums_ReturnsCorrectQueryable()
        {
            // Arrange
            var builder = ODataConventionModelBuilderFactory.Create();

            builder.EntitySet <EnumModel>("EnumModels");
            var model = builder.GetEdmModel();

            var context = new ODataQueryContext(model, typeof(EnumModel))
            {
                RequestContainer = new MockContainer()
            };
            var orderbyOption = new OrderByQueryOption("Flag", context);
            IEnumerable <EnumModel> enumModels = FilterQueryOptionTest.EnumModelTestData;

            // Act
            IQueryable queryable = orderbyOption.ApplyTo(enumModels.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IEnumerable <EnumModel> actualCustomers = Assert.IsAssignableFrom <IEnumerable <EnumModel> >(queryable);

            Assert.Equal(
                new int[] { 5, 2, 1, 3, 6 },
                actualCustomers.Select(enumModel => enumModel.Id));
        }
Exemple #8
0
        public void CanApplySkipOrderby()
        {
            var model   = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel();
            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockServiceProvider()
            };
            var orderbyOption = new OrderByQueryOption("Name", context);
            var skipOption    = new SkipQueryOption("1", context);

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

            IQueryable queryable = orderbyOption.ApplyTo(customers);

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

            Assert.Equal(2, results.Length);
            Assert.Equal(3, results[0].Id);
            Assert.Equal(1, results[1].Id);
        }
        public void CanApplyOrderBy_WithParameterAlias()
        {
            // Arrange
            var model = new ODataModelBuilder().Add_Customer_EntityType_With_Address().Add_Address_ComplexType().GetServiceModel();

            var parser = new ODataQueryOptionParser(
                model,
                model.FindType("Microsoft.AspNet.OData.Test.Builder.TestModels.Customer"),
                model.FindDeclaredNavigationSource("Default.Container.Customers"),
                new Dictionary <string, string> {
                { "$orderby", "@q desc,@p asc" }, { "@q", "Address/HouseNumber" }, { "@p", "CustomerId" }
            });

            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockContainer()
            };
            var orderByOption = new OrderByQueryOption("@q desc,@p asc", context, parser);

            var customers = (new List <Customer> {
                new Customer {
                    CustomerId = 1, Address = new Address {
                        HouseNumber = 2
                    }
                },
                new Customer {
                    CustomerId = 2, Address = new Address {
                        HouseNumber = 1
                    }
                },
                new Customer {
                    CustomerId = 3, Address = new Address {
                        HouseNumber = 3
                    }
                },
                new Customer {
                    CustomerId = 4, Address = new Address {
                        HouseNumber = 2
                    }
                },
                new Customer {
                    CustomerId = 5, Address = new Address {
                        HouseNumber = 1
                    }
                },
            }).AsQueryable();

            // Act
            var results = orderByOption.ApplyTo(customers).ToArray();

            // Assert
            Assert.Equal(3, results[0].CustomerId);
            Assert.Equal(1, results[1].CustomerId);
            Assert.Equal(4, results[2].CustomerId);
            Assert.Equal(2, results[3].CustomerId);
            Assert.Equal(5, results[4].CustomerId);
        }
        public void ApplyInValidOrderbyQueryThrows(string orderbyValue)
        {
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel();
            var context = new ODataQueryContext(model, typeof(Customer), "Customers");
            var orderby = new OrderByQueryOption(orderbyValue, context);

            Assert.Throws<ODataException>(() =>
                orderby.ApplyTo(ODataQueryOptionTest.Customers));
        }
        public void OrderByDuplicateItThrows()
        {
            // Arrange
            var context       = new ODataQueryContext(EdmCoreModel.Instance, typeof(int));
            var orderbyOption = new OrderByQueryOption("$it, $it", context);

            // Act
            ExceptionAssert.Throws <ODataException>(
                () => orderbyOption.ApplyTo(Enumerable.Empty <int>().AsQueryable()),
                "Multiple '$it' nodes are not supported in '$orderby'.");
        }
        public void ApplyInValidOrderbyQueryThrows(string orderbyValue)
        {
            var model   = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel();
            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockContainer()
            };
            var orderby = new OrderByQueryOption(orderbyValue, context);

            ExceptionAssert.Throws <ODataException>(() =>
                                                    orderby.ApplyTo(ODataQueryOptionTest.Customers));
        }
        public void ApplyTo_WithUnTypedContext_Throws_InvalidOperation()
        {
            // Arrange
            CustomersModelWithInheritance model   = new CustomersModelWithInheritance();
            ODataQueryContext             context = new ODataQueryContext(model.Model, model.Customer);
            OrderByQueryOption            orderBy = new OrderByQueryOption("ID desc", context);
            IQueryable queryable = new Mock <IQueryable>().Object;

            // Act & Assert
            ExceptionAssert.Throws <NotSupportedException>(() => orderBy.ApplyTo(queryable),
                                                           "The query option is not bound to any CLR type. 'ApplyTo' is only supported with a query option bound to a CLR type.");
        }
        public static Expression ToExpression <TPublicEntity>(this OrderByQueryOption filter) where TPublicEntity : BaseDto
        {
            if (filter == null)
            {
                throw new ArgumentNullException(nameof(filter));
            }

            IQueryable queryable = Enumerable.Empty <TPublicEntity>().AsQueryable();

            queryable = filter.ApplyTo(queryable, new ODataQuerySettings());
            return(queryable.Expression);
        }
Exemple #15
0
        public void CanOrderByChildPropertyAscending()
        {
            // Arrange
            var query = new List <Product>
            {
                new Product {
                    Category = new Category {
                        Description = "b"
                    }
                },
                new Product {
                    Category = new Category {
                        Description = "a"
                    }
                },
                new Product {
                    Category = new Category {
                        Description = "d"
                    }
                },
                new Product {
                    Category = new Category {
                        Description = "c"
                    }
                }
            }
            .AsQueryable();

            var sortPropertyPath = string.Concat(
                nameof(Product.Category),
                ".",
                nameof(Category.Description));

            var orderByNodes = new List <OrderByNode>
            {
                new OrderByNode(sortPropertyPath)
            };

            var options = new OrderByQueryOption(orderByNodes);

            // Act
            var results = options.ApplyTo(query).ToList();

            // Assert
            Assert.Collection(
                results,
                o => Assert.Equal("a", o.Category.Description),
                o => Assert.Equal("b", o.Category.Description),
                o => Assert.Equal("c", o.Category.Description),
                o => Assert.Equal("d", o.Category.Description));
        }
        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());
        }
        public void OrderByDuplicatePropertyOfComplexTypeThrows()
        {
            // Arrange
            var model = new ODataModelBuilder().Add_Customer_EntityType_With_Address().Add_Customers_EntitySet().GetServiceModel();

            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockContainer()
            };
            var orderbyOption = new OrderByQueryOption("Address/City, Address/City", context);

            // Act
            ExceptionAssert.Throws <ODataException>(
                () => orderbyOption.ApplyTo(Enumerable.Empty <Customer>().AsQueryable()),
                "Duplicate property named 'Address/City' is not supported in '$orderby'.");
        }
        public static Expression <Func <TElement, bool> > ToExpression <TElement>(this OrderByQueryOption orderBy)
        {
            var        param     = Expression.Parameter(typeof(TElement));
            IQueryable queryable = Enumerable.Empty <TElement>().AsQueryable();

            if (orderBy != null)
            {
                queryable = orderBy.ApplyTo(queryable, new ODataQuerySettings());
                var mce = queryable.Expression as MethodCallExpression;
                if (mce != null)
                {
                    var quote = mce.Arguments[1] as UnaryExpression;
                    if (quote != null)
                    {
                        return(quote.Operand as Expression <Func <TElement, bool> >);
                    }
                }
            }
            return(Expression.Lambda <Func <TElement, bool> >(Expression.Constant(true), param));
        }
        public void CanApplySkipOrderby()
        {
            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("1", context);

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

            IQueryable queryable = orderbyOption.ApplyTo(customers);
            queryable = skipOption.ApplyTo(queryable, new ODataQuerySettings());
            var results = ((IQueryable<Customer>)queryable).ToArray();
            Assert.Equal(2, results.Length);
            Assert.Equal(3, results[0].CustomerId);
            Assert.Equal(1, results[1].CustomerId);
        }
        public void ApplyToEnums_ReturnsCorrectQueryable()
        {
            // Arrange
            var builder = new ODataConventionModelBuilder();
            builder.EntitySet<EnumModel>("EnumModels");
            var model = builder.GetEdmModel();

            var context = new ODataQueryContext(model, typeof(EnumModel));
            var orderbyOption = new OrderByQueryOption("Flag", context, null);
            IEnumerable<EnumModel> enumModels = FilterQueryOptionTest.EnumModelTestData;

            // Act
            IQueryable queryable = orderbyOption.ApplyTo(enumModels.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IEnumerable<EnumModel> actualCustomers = Assert.IsAssignableFrom<IEnumerable<EnumModel>>(queryable);
            Assert.Equal(
                new int[] { 2, 1, 3 },
                actualCustomers.Select(enumModel => enumModel.Id));
        }
        public void CanApplyOrderBy_WithNestedParameterAlias()
        {
            // Arrange
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel();

            var parser = new ODataQueryOptionParser(
                model,
                model.FindType("Microsoft.AspNet.OData.Test.Builder.TestModels.Customer"),
                model.FindDeclaredNavigationSource("Default.Container.Customers"),
                new Dictionary <string, string> {
                { "$orderby", "@p1" }, { "@p2", "Name" }, { "@p1", "@p2" }
            });

            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockContainer()
            };
            var orderByOption = new OrderByQueryOption("@p1", context, parser);

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

            // Act
            var results = orderByOption.ApplyTo(customers).ToArray();

            // Assert
            Assert.Equal(2, results[0].CustomerId);
            Assert.Equal(3, results[1].CustomerId);
            Assert.Equal(1, results[2].CustomerId);
        }
Exemple #22
0
        public void CanOrderByMultipleProperties()
        {
            // Arrange
            var query = new List <Product>
            {
                new Product {
                    Id = 2, Price = 1.23m
                },
                new Product {
                    Id = 4, Price = 5.23m
                },
                new Product {
                    Id = 1, Price = 1.23m
                },
                new Product {
                    Id = 3, Price = 0.23m
                }
            }
            .AsQueryable();

            var orderByNodes = new List <OrderByNode>
            {
                new OrderByNode(nameof(Product.Price), OrderByDirection.Descending),
                new OrderByNode(nameof(Product.Id))
            };

            var options = new OrderByQueryOption(orderByNodes);

            // Act
            var results = options.ApplyTo(query).ToList();

            // Assert
            Assert.Collection(
                results,
                o => Assert.Equal(4, o.Id),
                o => Assert.Equal(1, o.Id),
                o => Assert.Equal(2, o.Id),
                o => Assert.Equal(3, o.Id));
        }
Exemple #23
0
        public void CanOrderByDescending()
        {
            // Arrange
            var query = new List <Product>
            {
                new Product {
                    Id = 2
                },
                new Product {
                    Id = 1
                },
                new Product {
                    Id = 4
                },
                new Product {
                    Id = 3
                }
            }
            .AsQueryable();

            var orderByNodes = new List <OrderByNode>
            {
                new OrderByNode(nameof(Product.Id), OrderByDirection.Descending)
            };

            var options = new OrderByQueryOption(orderByNodes);

            // Act
            var results = options.ApplyTo(query).ToList();

            // Assert
            Assert.Collection(
                results,
                o => Assert.Equal(4, o.Id),
                o => Assert.Equal(3, o.Id),
                o => Assert.Equal(2, o.Id),
                o => Assert.Equal(1, o.Id));
        }
Exemple #24
0
        public void OrderByIsCaseInsensitive()
        {
            // Arrange
            var query = new List <Product>
            {
                new Product {
                    Id = 2
                },
                new Product {
                    Id = 1
                },
                new Product {
                    Id = 4
                },
                new Product {
                    Id = 3
                }
            }
            .AsQueryable();

            var orderByNodes = new List <OrderByNode>
            {
                new OrderByNode("iD")
            };

            var options = new OrderByQueryOption(orderByNodes);

            // Act
            var results = options.ApplyTo(query).ToList();

            // Assert
            Assert.Collection(
                results,
                o => Assert.Equal(1, o.Id),
                o => Assert.Equal(2, o.Id),
                o => Assert.Equal(3, o.Id),
                o => Assert.Equal(4, o.Id));
        }
        public void OrderByDuplicatePropertyThrows()
        {
            // Arrange
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel();

            var context = new ODataQueryContext(model, typeof(Customer));
            var orderbyOption = new OrderByQueryOption("Name, Name", context);

            // Act
            Assert.Throws<ODataException>(
                () => orderbyOption.ApplyTo(Enumerable.Empty<Customer>().AsQueryable()),
                "Duplicate property named 'Name' is not supported in '$orderby'.");
        }
        public void CanApplyOrderByDescThenByDesc()
        {
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel();
            var orderByOption = new OrderByQueryOption("Name desc,Website desc", new ODataQueryContext(model, typeof(Customer)));

            var customers = (new List<Customer>{
                new Customer { CustomerId = 1, Name = "ACME", Website = "http://www.acme.net" },
                new Customer { CustomerId = 2, Name = "AAAA", Website = "http://www.aaaa.com" },
                new Customer { CustomerId = 3, Name = "ACME", Website = "http://www.acme.com" }
            }).AsQueryable();

            var results = orderByOption.ApplyTo(customers).ToArray();
            Assert.Equal(1, results[0].CustomerId);
            Assert.Equal(3, results[1].CustomerId);
            Assert.Equal(2, results[2].CustomerId);
        }
        public async Task <IActionResult> OData(ODataQueryOptions <DeveloperDto> oDataQuery)
        {
            var edmModel     = EdmModelConfig.GetEdmModel();
            var edmEntitySet = edmModel.FindDeclaredEntitySet(nameof(Developer));

            var context = new ODataQueryContext(edmModel, typeof(Developer), oDataQuery.Context.Path);
            var edmType = context.ElementType;

            var parameters = new Dictionary <string, string>();

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Filter))
            {
                parameters.Add("$filter", oDataQuery.RawValues.Filter);
            }

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Expand))
            {
                parameters.Add("$expand", oDataQuery.RawValues.Expand);
            }

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.OrderBy))
            {
                parameters.Add("$orderby", oDataQuery.RawValues.OrderBy);
            }

            var parser = new ODataQueryOptionParser(edmModel, edmType, edmEntitySet, parameters);

            var queryable = (IQueryable <Developer>)_databaseContext.Developer;

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Filter))
            {
                var filter = new FilterQueryOption(oDataQuery.RawValues.Filter, context, parser);
                queryable = (IQueryable <Developer>)filter.ApplyTo(queryable, new ODataQuerySettings());
            }

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.OrderBy))
            {
                var orderBy = new OrderByQueryOption(oDataQuery.RawValues.OrderBy, context, parser);
                queryable = orderBy.ApplyTo(queryable, new ODataQuerySettings());
            }

            IQueryable <object> expandableQueryable = null;

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Expand))
            {
                var expand = new SelectExpandQueryOption(null, oDataQuery.RawValues.Expand, context, parser);
                expandableQueryable = (IQueryable <object>)expand.ApplyTo(queryable, new ODataQuerySettings());
            }

            int pageIndex    = 1;
            var hasPageIndex = oDataQuery.Request.Query.TryGetValue("$pageindex", out StringValues pageIndexRaw);

            if (hasPageIndex)
            {
                var isTrue = int.TryParse(pageIndexRaw, out int _pageIndexRaw);
                pageIndex = (isTrue && _pageIndexRaw > 0) ? _pageIndexRaw : pageIndex;
            }

            int pageSize    = 10;
            var hasPageSize = oDataQuery.Request.Query.TryGetValue("$pagesize", out StringValues pageSizeRaw);

            if (hasPageSize)
            {
                var isTrue = int.TryParse(pageSizeRaw, out int _pageSizeRaw);
                pageSize = (isTrue && _pageSizeRaw > 0) ? _pageSizeRaw : pageSize;
            }

            IQueryable <object> queryToExecute = expandableQueryable ?? queryable;
            var records = await queryToExecute.Skip((pageIndex - 1) *pageSize).Take(pageSize).ToListAsync();

            var count = await queryToExecute.CountAsync();

            var pageList = new PageList <Developer>(MapDomain(records).ToList(), count, pageIndex, pageSize);
            var response = PageListDto <DeveloperDto> .Map(pageList, DeveloperDto.MapDomainToDto);

            return(Ok(response));
        }
        public void ApplyTo_PropertyAliased_IfEnabled(bool modelAliasing, string propertyName)
        {
            // Arrange
            var builder = new ODataConventionModelBuilder { ModelAliasingEnabled = modelAliasing };
            builder.EntitySet<PropertyAlias>("PropertyAliases");
            var model = builder.GetEdmModel();

            var context = new ODataQueryContext(model, typeof(PropertyAlias));
            var orderByOption = new OrderByQueryOption(propertyName, context);
            IEnumerable<PropertyAlias> propertyAliases = FilterQueryOptionTest.PropertyAliasTestData;

            // Act
            IQueryable queryable = orderByOption.ApplyTo(propertyAliases.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IEnumerable<PropertyAlias> actualCustomers = Assert.IsAssignableFrom<IEnumerable<PropertyAlias>>(queryable);
            Assert.Equal(
                new[] { "abc", "def", "xyz" },
                actualCustomers.Select(propertyAlias => propertyAlias.FirstName));
        }
Exemple #29
0
        public override IQueryable ApplyTo(IQueryable query, ODataQuerySettings querySettings)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            if (querySettings == null)
            {
                throw new ArgumentNullException(nameof(querySettings));
            }

            var 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.ODataProperties().TotalCount == null)
            {
                long?count = InlineCount.GetEntityCount(result);
                if (count.HasValue)
                {
                    Request.ODataProperties().TotalCount = 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, querySettings);
            }

            if (Skip != null)
            {
                result = Skip.ApplyTo(result, querySettings);
            }

            if (Top != null)
            {
                result = Top.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);
        }
        public void ApplyTo_NestedProperties_WithDuplicatePathType_Succeeds()
        {
            // Arrange
            var model =
                new ODataModelBuilder().Add_Customer_EntityType_With_DuplicatedAddress()
                .Add_Customers_EntitySet()
                .GetEdmModel();
            var context = new ODataQueryContext(model, typeof(Customer))
            {
                RequestContainer = new MockServiceProvider()
            };
            var orderByOption = new OrderByQueryOption("City,Address/City,WorkAddress/City", context);
            var customers     = (new List <Customer>
            {
                new Customer
                {
                    Id = 1,
                    City = "B",
                    Address = new Address {
                        City = "B"
                    },
                    WorkAddress = new Address {
                        City = "B"
                    }
                },
                new Customer
                {
                    Id = 2,
                    City = "B",
                    Address = new Address {
                        City = "B"
                    },
                    WorkAddress = new Address {
                        City = "A"
                    }
                },
                new Customer
                {
                    Id = 3,
                    City = "B",
                    Address = new Address {
                        City = "A"
                    },
                    WorkAddress = new Address {
                        City = "A"
                    }
                },
                new Customer
                {
                    Id = 4,
                    City = "A",
                    Address = new Address {
                        City = "A"
                    },
                    WorkAddress = new Address {
                        City = "A"
                    }
                }
            }).AsQueryable();

            // Act
            var results = orderByOption.ApplyTo(customers).ToArray();

            // Assert
            Assert.Equal(4, results[0].Id);
            Assert.Equal(3, results[1].Id);
            Assert.Equal(2, results[2].Id);
            Assert.Equal(1, results[3].Id);
        }
        public void CanApplyOrderBy_WithCollectionCount(string orderby)

        {
            // Arrange
            var model = new ODataModelBuilder()
                        .Add_Order_EntityType()
                        .Add_Customer_EntityType_With_Address()
                        .Add_CustomerOrders_Relationship()
                        .Add_Customer_EntityType_With_CollectionProperties()
                        .Add_Customers_EntitySet()
                        .GetEdmModel();

            var parser = new ODataQueryOptionParser(
                model,
                model.FindType("Microsoft.AspNetCore.OData.Tests.Models.Customer"),
                model.FindDeclaredNavigationSource("Default.Container.Customers"),
                new Dictionary <string, string> {
                { "$orderby", orderby }
            });

            var orderByOption = new OrderByQueryOption(orderby, new ODataQueryContext(model, typeof(Customer)), parser);

            var customers = (new List <Customer>
            {
                new Customer
                {
                    Id = 1,
                    Name = "Andy",
                    Orders = new List <Order>
                    {
                        new Order {
                            OrderId = 1
                        },
                        new Order {
                            OrderId = 2
                        }
                    },
                    Addresses = new List <Address>
                    {
                        new Address {
                            City = "1"
                        },
                        new Address {
                            City = "2"
                        }
                    },
                    Aliases = new List <string> {
                        "1", "2"
                    }
                },
                new Customer
                {
                    Id = 2,
                    Name = "Aaron",
                    Orders = new List <Order>
                    {
                        new Order {
                            OrderId = 3
                        }
                    },
                    Addresses = new List <Address>
                    {
                        new Address {
                            City = "3"
                        }
                    },
                    Aliases = new List <string> {
                        "3"
                    }
                },
                new Customer {
                    Id = 3, Name = "Alex"
                }
            }).AsQueryable();

            // Act
            var results = orderByOption.ApplyTo(customers).ToArray();

            // Assert
            Assert.Equal(3, results[0].Id);
            Assert.Equal(2, results[1].Id);
            Assert.Equal(1, results[2].Id);
        }
        public void ApplyTo_WithUnTypedContext_Throws_InvalidOperation()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataQueryContext context = new ODataQueryContext(model.Model, model.Customer);
            OrderByQueryOption orderBy = new OrderByQueryOption("ID desc", context);
            IQueryable queryable = new Mock<IQueryable>().Object;

            // Act & Assert
            Assert.Throws<NotSupportedException>(() => orderBy.ApplyTo(queryable),
                "The query option is not bound to any CLR type. 'ApplyTo' is only supported with a query option bound to a CLR type.");
        }
        public void OrderByDuplicateItThrows()
        {
            // Arrange
            var context = new ODataQueryContext(EdmCoreModel.Instance, typeof(int));
            var orderbyOption = new OrderByQueryOption("$it, $it", context);

            // Act
            Assert.Throws<ODataException>(
                () => orderbyOption.ApplyTo(Enumerable.Empty<int>().AsQueryable()),
                "Multiple '$it' nodes are not supported in '$orderby'.");
        }
Exemple #34
0
        public static Func <IQueryable <Creative>, IOrderedQueryable <Creative> > ToExpression <TElement>(this OrderByQueryOption orderBy)
        {
            if (orderBy == null)
            {
                return(null);
            }

            IQueryable queryable = Enumerable.Empty <TElement>().AsQueryable();
            var        param     = Expression.Parameter(typeof(Creative));
            //queryable = orderBy.ApplyTo(queryable, new ODataQuerySettings());

            IOrderedQueryable <Creative> orderQueryable = (IOrderedQueryable <Creative>)orderBy.ApplyTo(queryable, new ODataQuerySettings());
            Func <IQueryable <Creative>, IOrderedQueryable <Creative> > orderingFunc = query => orderQueryable;

            return(orderingFunc);
        }
        // GET: odata/MyEntities
        //[EnableQuery]
        //public IQueryable<MyEntity> GetMyEntities(ODataQueryOptions opts)
        //{
        //    IQueryable results = opts.ApplyTo(db.MyEntities.AsQueryable());
        //    return results as IQueryable<MyEntity>;
        //}

        // GET: odata/MyEntities
        //[EnableQuery]
        public IQueryable <MyEntity> GetMyEntities(ODataQueryOptions opts)
        {
            var settings = new ODataValidationSettings()
            {
                // Initialize settings as needed.
                AllowedFunctions = AllowedFunctions.AllMathFunctions
            };

            opts.Validate(settings);
            //IQueryable results = db.MyEntities.AsQueryable<MyEntity>();
            //if (opts.Filter != null)
            //{
            //    results = opts.Filter.ApplyTo(results, new ODataQuerySettings() { EnableConstantParameterization = false, EnsureStableOrdering = false });
            //}

            //results = results.Decompile();
            //results.Decompile
            //IQueryable results = MyApplyToWithDecompile(db.MyEntities.AsQueryable(), opts);
            //return results as IQueryable<MyEntity>;
            //return db.MyEntities;


            IQueryable         result        = db.MyEntities.AsQueryable();
            ODataQuerySettings querySettings = new ODataQuerySettings()
            {
                EnableConstantParameterization = false, EnsureStableOrdering = false
            };

            // Construct the actual query and apply them in the following order: filter, orderby, skip, top
            if (opts.Filter != null)
            {
                result = opts.Filter.ApplyTo(result, querySettings);
                result = ((result as IQueryable <MyEntity>).Decompile()).AsQueryable();
            }

            if (opts.InlineCount != null && Request.ODataProperties().TotalCount == null)
            {
                long?count = opts.InlineCount.GetEntityCount(result);
                if (count.HasValue)
                {
                    Request.ODataProperties().TotalCount = count.Value;
                }
            }

            OrderByQueryOption orderBy = opts.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 &&
                (opts.Skip != null || opts.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(opts.Context)
                            : EnsureStableSortOrderBy(orderBy, opts.Context);
            }

            if (orderBy != null)
            {
                result = orderBy.ApplyTo(result, querySettings);
            }

            if (opts.Skip != null)
            {
                result = opts.Skip.ApplyTo(result, querySettings);
            }

            if (opts.Top != null)
            {
                result = opts.Top.ApplyTo(result, querySettings);
            }

            if (opts.SelectExpand != null)
            {
                Request.ODataProperties().SelectExpandClause = opts.SelectExpand.SelectExpandClause;
                result = opts.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.ODataProperties().NextLink == null)
                {
                    Uri nextPageLink = GetNextPageLink(Request, querySettings.PageSize.Value);
                    Request.ODataProperties().NextLink = nextPageLink;
                }
            }

            return(result as IQueryable <MyEntity>); // this compiles and works in most cases except when using $top with anything else.  Even if no results are found.
            //return result.AsQueryable(); // this doesn't compile, Error: Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Linq.IQueryable<MyEntity>.  An explicit conversion exists (are you missing a cast?)
        }
        public void ApplyTo_NestedProperties_HandlesNullPropagation_Succeeds()
        {
            // 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)));

            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();

            // Act
            var results = orderByOption.ApplyTo(customers).ToArray();

            // Assert
            Assert.Equal(1, results[0].CustomerId);
            Assert.Equal(3, results[1].CustomerId);
            Assert.Equal(2, results[2].CustomerId);
        }
        public void CanApplyOrderBy_WithParameterAlias()
        {
            // Arrange
            var model = new ODataModelBuilder().Add_Customer_EntityType_With_Address().Add_Address_ComplexType().GetServiceModel();

            var parser = new ODataQueryOptionParser(
                model,
                model.FindType("System.Web.OData.Builder.TestModels.Customer"),
                model.FindDeclaredNavigationSource("Default.Container.Customers"),
                new Dictionary<string, string> { { "$orderby", "@q desc,@p asc" }, { "@q", "Address/HouseNumber" }, { "@p", "CustomerId" } });

            var orderByOption = new OrderByQueryOption("@q desc,@p asc", new ODataQueryContext(model, typeof(Customer)), parser);

            var customers = (new List<Customer>{
                new Customer { CustomerId = 1, Address = new Address{HouseNumber = 2}},
                new Customer { CustomerId = 2, Address = new Address{HouseNumber = 1}},
                new Customer { CustomerId = 3, Address = new Address{HouseNumber = 3}},
                new Customer { CustomerId = 4, Address = new Address{HouseNumber = 2}},
                new Customer { CustomerId = 5, Address = new Address{HouseNumber = 1}},
            }).AsQueryable();

            // Act
            var results = orderByOption.ApplyTo(customers).ToArray();

            // Assert
            Assert.Equal(3, results[0].CustomerId);
            Assert.Equal(1, results[1].CustomerId);
            Assert.Equal(4, results[2].CustomerId);
            Assert.Equal(2, results[3].CustomerId);
            Assert.Equal(5, results[4].CustomerId);
        }
        public void CanApplyOrderBy()
        {
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel();
            var orderByOption = new OrderByQueryOption("Name", 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 = orderByOption.ApplyTo(customers).ToArray();
            Assert.Equal(2, results[0].CustomerId);
            Assert.Equal(3, results[1].CustomerId);
            Assert.Equal(1, results[2].CustomerId);
        }
        public void CanApplyOrderBy_WithNestedParameterAlias()
        {
            // Arrange
            var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel();

            var parser = new ODataQueryOptionParser(
                model,
                model.FindType("System.Web.OData.Builder.TestModels.Customer"),
                model.FindDeclaredNavigationSource("Default.Container.Customers"),
                new Dictionary<string, string> { { "$orderby", "@p1" }, { "@p2", "Name" }, { "@p1", "@p2" } });

            var orderByOption = new OrderByQueryOption("@p1", new ODataQueryContext(model, typeof(Customer)), parser);

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

            // Act
            var results = orderByOption.ApplyTo(customers).ToArray();

            // Assert
            Assert.Equal(2, results[0].CustomerId);
            Assert.Equal(3, results[1].CustomerId);
            Assert.Equal(1, results[2].CustomerId);
        }