public void ParseOrderby()
 {
     ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://www.odata.com/OData"), new Uri("http://www.odata.com/OData/People?$orderby=Name asc"));
     ODataUri parsedUri = parser.ParseUri();
     parsedUri.OrderBy.Expression.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp());
     parsedUri.OrderBy.Direction.Should().Be(OrderByDirection.Ascending);
 }
Exemple #2
0
        public async Task RouteAsync(RouteContext context)
        {
            var request = context.HttpContext.Request;

            Uri uri;
            PathString remaining;
            if (!request.Path.StartsWithSegments(PathString.FromUriComponent("/" + _routePrefix), out remaining))
            {
                // Fallback to other routes.
                return;
            }

            uri = new Uri(remaining.ToString(), UriKind.Relative);
            
            context.HttpContext.ODataProperties().Model = _model;
            var parser = new ODataUriParser(_model, uri);
            var path = parser.ParsePath();
            context.HttpContext.ODataProperties().NewPath = path;
            context.HttpContext.ODataProperties().Path =
                context.HttpContext.ODataPathHandler().Parse(_model, "http://service-root/", remaining.ToString());
            context.HttpContext.ODataProperties().IsValidODataRequest = true;

            await m.RouteAsync(context);
            context.IsHandled = true;
        }
        public void BuildPath_AliasInFunctionImport()
        {
            Uri fullUri = new Uri("http://gobbledygook/GetPet4(id=@p1)?@p1=1.01M");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);
            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlConventions = ODataUrlConventions.Default;
            ODataUri odataUri = odataUriParser.ParseUri();

            IDictionary<string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;

            odataUri.Path.LastSegment.ShouldBeOperationImportSegment(HardCodedTestModel.GetFunctionImportForGetPet4()).And.Parameters.First().ShouldHaveParameterAliasNode("id", "@p1", EdmCoreModel.Instance.GetDecimal(false));
            aliasNodes["@p1"].ShouldBeConstantQueryNode(1.01M);

            ODataUriBuilder odataUriBuilder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri);
            Uri actualUri = odataUriBuilder.BuildUri();
            Assert.AreEqual(fullUri, actualUri);

            ODataUriBuilder uriBuilderWithKeyAsSegment = new ODataUriBuilder(ODataUrlConventions.KeyAsSegment, odataUri);
            actualUri = uriBuilderWithKeyAsSegment.BuildUri();
            Assert.AreEqual(fullUri, actualUri);

            ODataUriBuilder uriBuilderWithODataSimplified = new ODataUriBuilder(ODataUrlConventions.ODataSimplified, odataUri);
            actualUri = uriBuilderWithODataSimplified.BuildUri();
            Assert.AreEqual(fullUri, actualUri);
        }
Exemple #4
0
        public void PathNavigation()
        {
            ODataUriParser parser = new ODataUriParser(model, new Uri("http://www.potato.com/"), new Uri("http://www.potato.com/Customers(5)/Orders"));
            var result = parser.ParsePath();
            ApprovalVerify(QueryNodeToStringVisitor.ToString(result));

            this.TestExtensions("CustoMERS(5)/OrDErs");
        }
Exemple #5
0
        public void PathEntity()
        {
            ODataUriParser parser = new ODataUriParser(model, new Uri("http://www.potato.com/"), new Uri("http://www.potato.com/Orders(2)"));
            var result = parser.ParsePath();
            ApprovalVerify(QueryNodeToStringVisitor.ToString(result));

            this.TestExtensions("OrDERS(2)");
        }
 private string GetContextUrlPathString(Uri queryUri)
 {
     ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, queryUri);
     odataUriParser.UrlConventions = ODataUrlConventions.Default;
     ODataUri odataUri = odataUriParser.ParseUri();
     ODataPath odataPath = odataUri.Path;
    return odataPath.ToContextUrlPathString();
 }
 public void ParseFilter()
 {
     ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://www.odata.com/OData"), new Uri("http://www.odata.com/OData/People?$filter=Name eq 'Bob'"));
     ODataUri parsedUri = parser.ParseUri();
     var equalOperator = parsedUri.Filter.Expression.ShouldBeBinaryOperatorNode(BinaryOperatorKind.Equal).And;
     equalOperator.Left.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp());
     equalOperator.Right.ShouldBeConstantQueryNode("Bob");
 }
Exemple #8
0
        public void PathComplex()
        {
            ODataUriParser parser = new ODataUriParser(model, new Uri("http://www.potato.com/"), new Uri("http://www.potato.com/Customers(-32)/HomeAddress"));
            var result = parser.ParsePath();
            ApprovalVerify(QueryNodeToStringVisitor.ToString(result));

            this.TestExtensions("CustomErs(-32)/HOMEAddress");
        }
Exemple #9
0
        public void PathBatch()
        {
            ODataUriParser parser = new ODataUriParser(model, new Uri("http://www.potato.com/"), new Uri("http://www.potato.com/$batch"));
            var result = parser.ParsePath();
            ApprovalVerify(QueryNodeToStringVisitor.ToString(result));

            this.TestExtensions("$BATch");
        }
        public void ODataUriBuilderWithEntitySet()
        {
            Uri fullUri = new Uri("http://www.example.com/People?$filter=MyDog%2FColor%20eq%20%27Brown%27&$select=ID&$expand=MyDog&$orderby=ID&$top=1&$skip=2&$count=true&$search=FA");
            ODataUriParser odataUriParser = new ODataUriParser(this.GetModel(), serviceRoot, fullUri);
            odataUriParser.UrlConventions = ODataUrlConventions.Default;
            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            ODataUri odataUri = odataUriParser.ParseUri();

            //verify path
            EntitySetSegment entitySet = (EntitySetSegment)odataUri.Path.FirstSegment;
            Assert.AreEqual(entitySet.EntitySet.Name, "People");
            Assert.AreEqual(odataUri.Path.Count, 1);

            //verify $filter
            BinaryOperatorNode binaryOperator = (BinaryOperatorNode)odataUri.Filter.Expression;
            SingleValuePropertyAccessNode singleValueProperty = (SingleValuePropertyAccessNode)binaryOperator.Left;
            SingleNavigationNode singleNavigation = (SingleNavigationNode)singleValueProperty.Source;
            ConstantNode constantNode = (ConstantNode)binaryOperator.Right;

            Assert.AreEqual(binaryOperator.OperatorKind, BinaryOperatorKind.Equal);
            Assert.AreEqual(singleValueProperty.Property.Name, "Color");
            Assert.AreEqual(singleNavigation.NavigationProperty.Name, "MyDog");
            Assert.AreEqual(constantNode.LiteralText, "'Brown'");

            //verify $select and $expand
            IEnumerable<SelectItem> selectItems = odataUri.SelectAndExpand.SelectedItems;
            foreach (ExpandedNavigationSelectItem selectItem in selectItems)
            {
                NavigationPropertySegment navigationProperty = (NavigationPropertySegment)selectItem.PathToNavigationProperty.FirstSegment;
                Assert.AreEqual(navigationProperty.NavigationProperty.Name, "MyDog");
                break;
            }

            //verify $orderby
            SingleValuePropertyAccessNode orderby = (SingleValuePropertyAccessNode)odataUri.OrderBy.Expression;
            Assert.AreEqual(orderby.Property.Name, "ID");

            //verify $top
            Assert.AreEqual(odataUri.Top, 1);

            //verify $skip
            Assert.AreEqual(odataUri.Skip, 2);

            //verify $count
            Assert.AreEqual(odataUri.QueryCount, true);

            //verify $search
            SearchTermNode searchTermNode = (SearchTermNode)odataUri.Search.Expression;
            Assert.AreEqual(searchTermNode.Text, "FA");

            ODataUriBuilder odataUriBuilder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri);
            Uri actualUri = odataUriBuilder.BuildUri();
            Assert.AreEqual(new Uri("http://www.example.com/People?$filter=MyDog%2FColor%20eq%20%27Brown%27&$select=ID%2CMyDog&$expand=MyDog&$orderby=ID&$top=1&$skip=2&$count=true&$search=FA"), actualUri);

            ODataUriBuilder uriBuilderWithKeyAsSegment = new ODataUriBuilder(ODataUrlConventions.KeyAsSegment, odataUri);
            actualUri = uriBuilderWithKeyAsSegment.BuildUri();
            Assert.AreEqual(new Uri("http://www.example.com/People?$filter=MyDog%2FColor%20eq%20%27Brown%27&$select=ID%2CMyDog&$expand=MyDog&$orderby=ID&$top=1&$skip=2&$count=true&$search=FA"), actualUri);
        }
 public void ParsePathWithValue()
 {
     ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://www.odata.com/OData"), new Uri("http://www.odata.com/OData/People(1)/$value"));
     ODataUri parsedUri = parser.ParseUri();
     List<ODataPathSegment> path = parsedUri.Path.ToList();
     path[0].ShouldBeEntitySetSegment(HardCodedTestModel.GetPeopleSet());
     path[1].ShouldBeKeySegment(new KeyValuePair<string, object>("ID", 1));
     path[2].ShouldBeValueSegment();
 }
 public void ParsePathWithLinks()
 {
     ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://www.odata.com/OData"), new Uri("http://www.odata.com/OData/People(1)/MyDog/$ref"));
     ODataUri parsedUri = parser.ParseUri();
     List<ODataPathSegment> path = parsedUri.Path.ToList();
     path[0].ShouldBeEntitySetSegment(HardCodedTestModel.GetPeopleSet());
     path[1].ShouldBeKeySegment(new KeyValuePair<string, object>("ID", 1));
     path[2].ShouldBeNavigationPropertyLinkSegment(HardCodedTestModel.GetPersonMyDogNavProp());
 }
        public static Uri UriBuilder(Uri queryUri, ODataUrlConventions urlConventions, ODataUriParserSettings settings)
        {
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, ServiceRoot, queryUri);
            SetODataUriParserSettingsTo(settings, odataUriParser.Settings);
            odataUriParser.UrlConventions = urlConventions;
            ODataUri odataUri = odataUriParser.ParseUri();

            ODataUriBuilder odataUriBuilder = new ODataUriBuilder(urlConventions, odataUri);
            return odataUriBuilder.BuildUri();
        }
Exemple #14
0
        private static void KeyAfterFunction()
        {
            Console.WriteLine("TestKeyAfterFunction");
            var parser = new ODataUriParser(
                extModel.Model,
                ServiceRoot,
                new Uri("http://demo/odata.svc/People(2)/TestNS.GetFriends(2)"));

            var path=parser.ParsePath();
            Console.WriteLine(path.ToLogString());
        }
Exemple #15
0
        private static void KeyContainingSpecialChar()
        {
            Console.WriteLine("KeyContainingSpecialChar");
            var parser = new ODataUriParser(
                extModel.Model,
                ServiceRoot,
                new Uri("http://demo/odata.svc/Resources('w%23j')"));

            var path = parser.ParsePath();
            Console.WriteLine(path.ToLogString());
        }
        /// <summary>Initializes a new <see cref="RequestExpressionParser"/>.</summary>
        /// <param name="service">Service with data and configuration.</param>
        /// <param name="requestDescription">RequestDescription instance containing information about the current request being parsed.</param>
        internal RequestExpressionParser(IDataService service, RequestDescription requestDescription)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(requestDescription != null, "requestDescription != null");

            this.provider = service.Provider;

            this.model = this.provider.GetMetadataProviderEdmModel();

            this.odataUriParser = RequestUriProcessor.CreateUriParserWithBatchReferenceCallback(service, service.OperationContext.AbsoluteRequestUri);
        }
Exemple #17
0
        private static void FilterOnOpenProperty()
        {
            Console.WriteLine("FilterOnOpenProperty");
            var parser = new ODataUriParser(
                extModel.Model,
                ServiceRoot,
                new Uri("http://demo/odata.svc/Resources?$filter=Name eq 'w'"));

            var filter = parser.ParseFilter();
            Console.WriteLine(filter.Expression.ToLogString());
        }
 public void ParseSelectExpand()
 {
     ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://www.odata.com/OData"), new Uri("http://www.odata.com/OData/Dogs?$select=Color, MyPeople&$expand=MyPeople"));
     ODataUri parsedUri = parser.ParseUri();
     parsedUri.SelectAndExpand.SelectedItems.First().ShouldBePathSelectionItem(new ODataPath(new PropertySegment(HardCodedTestModel.GetDogColorProp())));
     var myPeopleExpand = parsedUri.SelectAndExpand.SelectedItems.Last().ShouldBeSelectedItemOfType<ExpandedNavigationSelectItem>().And;
     myPeopleExpand.PathToNavigationProperty.Single().ShouldBeNavigationPropertySegment(HardCodedTestModel.GetDogMyPeopleNavProp());
     var myPeopleSelectExpand = myPeopleExpand.SelectAndExpand;
     myPeopleSelectExpand.AllSelected.Should().BeTrue();
     myPeopleSelectExpand.SelectedItems.Should().BeEmpty();
 }
Exemple #19
0
        /// <summary>
        /// Parses the specified URI and wraps the results in a QueryContext.
        /// </summary>
        /// <param name="requestUri">The URI to parse.</param>
        /// <param name="model">The data store model.</param>
        /// <returns>The parsed URI wrapped in a QueryContext.</returns>
        public static QueryContext ParseUri(Uri requestUri, IEdmModel model)
        {
            var requestUriParts = requestUri.OriginalString.Split('?');
            var queryPath = requestUriParts.First();
            if (requestUriParts.Count() > 1)
            {
                throw new NotSupportedException("Query option is not supported by the service yet.");
            }

            ODataUriParser uriParser = new ODataUriParser(model, ServiceConstants.ServiceBaseUri, new Uri(queryPath, UriKind.Absolute));
            return new QueryContext { QueryPath = uriParser.ParsePath() };
        }
 public void PathBaseSingletonWithKeyShouldFail()
 {
     ODataUriParser parser = new ODataUriParser(model, new Uri("http://www.potato.com/"), new Uri("http://www.potato.com/SpecialOrder(1)"));
     try
     {
         parser.ParsePath();
     }
     catch (ODataException e)
     {
         var expected = ODataExpectedExceptions.ODataException("RequestUriProcessor_SyntaxError");
         expected.ExpectedMessage.Verifier.VerifyMatch("RequestUriProcessor_SyntaxError", e.Message);
     }
 }
        public void ParseKeyTemplateWithTemplateParserWithWithWhitespaceOutsideofTempateExpressionTest()
        {
            var uriParser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("People(  {1} )", UriKind.Relative))
            {
                EnableUriTemplateParsing = true
            };

            var path = uriParser.ParsePath();
            var keySegment = path.LastSegment.As<KeySegment>();
            KeyValuePair<string, object> keypair = keySegment.Keys.Single();
            keypair.Key.Should().Be("ID");
            keypair.Value.As<UriTemplateExpression>().ShouldBeEquivalentTo(new UriTemplateExpression { LiteralText = "{1}", ExpectedType = keySegment.EdmType.As<IEdmEntityType>().DeclaredKey.Single().Type });
        }
        public void ParseKeyTemplateAsSegmentWithTemplateParser()
        {
            var uriParser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://host"), new Uri("http://host/People/{1}"))
            {
                EnableUriTemplateParsing = true,
                UrlConventions = ODataUrlConventions.KeyAsSegment
            };

            var path = uriParser.ParsePath();
            var keySegment = path.LastSegment.As<KeySegment>();
            KeyValuePair<string, object> keypair = keySegment.Keys.Single();
            keypair.Key.Should().Be("ID");
            keypair.Value.As<UriTemplateExpression>().ShouldBeEquivalentTo(new UriTemplateExpression { LiteralText = "{1}", ExpectedType = keySegment.EdmType.As<IEdmEntityType>().DeclaredKey.Single().Type });
        }
        [InlineData("ID", "Orders($select=ID),Orders($expand=Customer($select=ID))", true, "ID")] // deep expand and selects
        public void GetPropertiesToBeSelected_Selects_ExpectedProperties_OnCustomer(
            string select, string expand, bool specialCustomer, string structuralPropertiesToSelect)
        {
            // Arrange
            SelectExpandClause selectExpandClause =
                new ODataUriParser(_model.Model, serviceRoot: null).ParseSelectAndExpand(select, expand,  _model.Customer, _model.Customers);
            IEdmEntityType entityType = specialCustomer ? _model.SpecialCustomer : _model.Customer;

            // Act
            SelectExpandNode selectExpandNode = new SelectExpandNode(selectExpandClause, entityType, _model.Model);
            var result = selectExpandNode.SelectedStructuralProperties;

            // Assert
            Assert.Equal(structuralPropertiesToSelect, String.Join(",", result.Select(p => p.Name).OrderBy(n => n)));
        }
 public void NoneQueryOptionShouldWork()
 {
     var uriParser = new ODataUriParser(HardCodedTestModel.TestModel, ServiceRoot, FullUri);
     var path = uriParser.ParsePath();
     path.Should().HaveCount(1);
     path.LastSegment.ShouldBeEntitySetSegment(HardCodedTestModel.GetPeopleSet());
     uriParser.ParseFilter().Should().BeNull();
     uriParser.ParseSelectAndExpand().Should().BeNull();
     uriParser.ParseOrderBy().Should().BeNull();
     uriParser.ParseTop().Should().Be(null);
     uriParser.ParseSkip().Should().Be(null);
     uriParser.ParseCount().Should().Be(null);
     uriParser.ParseSearch().Should().BeNull();
     uriParser.ParseSkipToken().Should().BeNull();
     uriParser.ParseDeltaToken().Should().BeNull();
 }
        /// <summary>
        /// Apply filter to the given resouce expression
        /// </summary>
        /// <param name="rootExpression"></param>
        /// <param name="entityInstanceType"></param>
        /// <param name="uriParser"></param>
        /// <param name="filterClause"></param>
        /// <returns></returns>
        public static Expression ApplyFilter(this Expression rootExpression, Type entityInstanceType, ODataUriParser uriParser, FilterClause filterClause)
        {
            ParameterExpression parameter = Expression.Parameter(entityInstanceType, "it");
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser = uriParser,
            };
            Expression filterNodeExpression = nodeToExpressionTranslator.TranslateNode(filterClause.Expression);

            // IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
            // translate to rootExpression.Where(filterNodeExpression)
            return Expression.Call(
                typeof(Enumerable),
                "Where",
                new Type[] { entityInstanceType },
                rootExpression,
                Expression.Lambda(filterNodeExpression, parameter));
        }
Exemple #26
0
        private static void TestCaseInsensitive()
        {
            Console.WriteLine("TestCaseInsensitive");
            var parser = new ODataUriParser(
                extModel.Model,
                ServiceRoot,
                new Uri("http://demo/odata.svc/People(1)/Pets/TestNS.Fish?$orderby=Color"));

            var path = parser.ParsePath();
            var clause = parser.ParseOrderBy();
            Console.WriteLine(path.ToLogString());
            Console.WriteLine(clause.Expression.ToLogString());

            var parser2 = new ODataUriParser(
                extModel.Model,
                ServiceRoot,
                new Uri("http://demo/odata.svc/people(1)/pets/testns.fish?$ORDERBY=color"))
            {
                Resolver = new ODataUriResolver { EnableCaseInsensitive = true }
            };

            // Identical to path and clause
            var path2 = parser2.ParsePath();
            var clause2 = parser2.ParseOrderBy();
            Console.WriteLine(path2.ToLogString());
            Console.WriteLine(clause2.Expression.ToLogString());

            // Query option parser also supports custom resolver
            var parser3 = new ODataQueryOptionParser(
                extModel.Model,
                extModel.Fish,
                extModel.PetSet,
                new Dictionary<string, string>
                {
                    {"$orderby", "color"}
                })
            {
                Resolver = new ODataUriResolver { EnableCaseInsensitive = true }
            };
            var clause3 = parser3.ParseOrderBy();
            Console.WriteLine(clause3.Expression.ToLogString());
        }
 public void EmptyValueQueryOptionShouldWork()
 {
     var uriParser = new ODataUriParser(HardCodedTestModel.TestModel, ServiceRoot, new Uri(FullUri, "?$filter=&$select=&$expand=&$orderby=&$top=&$skip=&$count=&$search=&$unknow=&$unknowvalue&$skiptoken=&$deltatoken="));
     var path = uriParser.ParsePath();
     path.Should().HaveCount(1);
     path.LastSegment.ShouldBeEntitySetSegment(HardCodedTestModel.GetPeopleSet());
     uriParser.ParseFilter().Should().BeNull();
     var results = uriParser.ParseSelectAndExpand();
     results.AllSelected.Should().BeTrue();
     results.SelectedItems.Should().HaveCount(0);
     uriParser.ParseOrderBy().Should().BeNull();
     Action action = () => uriParser.ParseTop();
     action.ShouldThrow<ODataException>().WithMessage(Strings.SyntacticTree_InvalidTopQueryOptionValue(""));
     action = () => uriParser.ParseSkip();
     action.ShouldThrow<ODataException>().WithMessage(Strings.SyntacticTree_InvalidSkipQueryOptionValue(""));
     action = () => uriParser.ParseCount();
     action.ShouldThrow<ODataException>().WithMessage(Strings.ODataUriParser_InvalidCount(""));
     action = () => uriParser.ParseSearch();
     action.ShouldThrow<ODataException>().WithMessage(Strings.UriQueryExpressionParser_ExpressionExpected(0, ""));
     uriParser.ParseSkipToken().Should().BeEmpty();
     uriParser.ParseDeltaToken().Should().BeEmpty();
 }
Exemple #28
0
        private static void TestUnqualified()
        {
            Console.WriteLine("TestUnqualified");
            var parser = new ODataUriParser(
                extModel.Model,
                ServiceRoot,
                new Uri("http://demo/odata.svc/People(1)/Addr/TestNS.GetZip"));

            var path = parser.ParsePath();
            Console.WriteLine(path.ToLogString());

            var parser2 = new ODataUriParser(
                extModel.Model,
                ServiceRoot,
                new Uri("http://demo/odata.svc/People(1)/addr/getzip"))
            {
                Resolver = new UnqualifiedODataUriResolver { EnableCaseInsensitive = true }
            };

            // Identical to path
            var path2 = parser2.ParsePath();
            Console.WriteLine(path2.ToLogString());
        }
        /// <summary>
        /// Apply orderby to the given resouce expression
        /// </summary>
        /// <param name="rootExpression"></param>
        /// <param name="entityInstanceType"></param>
        /// <param name="uriParser"></param>
        /// <param name="orderByClause"></param>
        /// <returns></returns>
        public static Expression ApplyOrderBy(this Expression rootExpression, Type entityInstanceType, ODataUriParser uriParser, OrderByClause orderByClause)
        {
            ParameterExpression parameter = Expression.Parameter(entityInstanceType, "it");
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser = uriParser,
            };

            Expression orderByNodeExpression = nodeToExpressionTranslator.TranslateNode(orderByClause.Expression);

            var keyType = EdmClrTypeUtils.GetInstanceType(orderByClause.Expression.TypeReference);

            if (orderByClause.Expression.TypeReference.IsNullable && keyType.IsValueType)
            {
                keyType = typeof(Nullable<>).MakeGenericType(keyType);
            }

            var method = orderByClause.Direction == OrderByDirection.Ascending ? "OrderBy" : "OrderByDescending";
            //OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
            var expression = Expression.Call(
                typeof(Enumerable),
                method,
                new Type[] { entityInstanceType, keyType },
                rootExpression,
                Expression.Lambda(orderByNodeExpression, parameter)) as Expression;
            var thenBy = orderByClause.ThenBy;
            while (null != thenBy)
            {
                expression = expression.ApplyThenBy(entityInstanceType, uriParser, thenBy);
                thenBy = thenBy.ThenBy;
            }
            return expression;
        }
        public void BuildPath_AliasInFunctionImport_enum()
        {
            Uri fullUri = new Uri("http://gobbledygook/GetPetCount(colorPattern=@p1)?@p1=Fully.Qualified.Namespace.ColorPattern'BlueYellowStriped'");
            ODataUriParser odataUriParser = new ODataUriParser(HardCodedTestModel.TestModel, serviceRoot, fullUri);
            SetODataUriParserSettingsTo(this.settings, odataUriParser.Settings);
            odataUriParser.UrlConventions = ODataUrlConventions.Default;
            ODataUri odataUri = odataUriParser.ParseUri();
            IDictionary<string, SingleValueNode> aliasNodes = odataUri.ParameterAliasNodes;

            OperationSegmentParameter p = odataUri.Path.LastSegment.ShouldBeOperationImportSegment(HardCodedTestModel.GetFunctionImportForGetPetCount()).And.Parameters.First();
            p.Name.Should().Be("colorPattern");
            p.Value.As<ParameterAliasNode>().Alias.Should().Be("@p1");
            p.Value.As<ParameterAliasNode>().TypeReference.IsEnum().Should().Be(true);
            p.Value.As<ParameterAliasNode>().TypeReference.Definition.FullTypeName().ShouldBeEquivalentTo("Fully.Qualified.Namespace.ColorPattern");
            aliasNodes["@p1"].As<ConstantNode>().Value.As<ODataEnumValue>().TypeName.Should().Be("Fully.Qualified.Namespace.ColorPattern");
            aliasNodes["@p1"].As<ConstantNode>().Value.As<ODataEnumValue>().Value.Should().Be("22");
            aliasNodes["@p1"].TypeReference.IsEnum().Should().Be(true);

            ODataUriBuilder odataUriBuilder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri);
            Uri actualUri = odataUriBuilder.BuildUri();
            Assert.AreEqual(fullUri, actualUri);

            ODataUriBuilder uriBuilderWithKeyAsSegment = new ODataUriBuilder(ODataUrlConventions.KeyAsSegment, odataUri);
            actualUri = uriBuilderWithKeyAsSegment.BuildUri();
            Assert.AreEqual(fullUri, actualUri);

            ODataUriBuilder uriBuilderWithODataSimplified = new ODataUriBuilder(ODataUrlConventions.ODataSimplified, odataUri);
            actualUri = uriBuilderWithODataSimplified.BuildUri();
            Assert.AreEqual(fullUri, actualUri);
        }