public Expression ApplyNavigation(Expression source, IReadOnlyList <OeParseNavigationSegment> parseNavigationSegments)
        {
            if (parseNavigationSegments == null)
            {
                return(source);
            }

            Type sourceItemType = OeExpressionHelper.GetCollectionItemType(source.Type);

            foreach (OeParseNavigationSegment parseNavigationSegment in parseNavigationSegments)
            {
                Type selectType;
                ParameterExpression parameter;
                Expression          e;
                if (parseNavigationSegment.NavigationSegment == null) //EntitySetSegment, KeySegment
                {
                    parameter  = Visitor.Parameter;
                    e          = source;
                    selectType = sourceItemType;
                }
                else
                {
                    parameter = Expression.Parameter(sourceItemType);
                    PropertyInfo navigationClrProperty = sourceItemType.GetProperty(parseNavigationSegment.NavigationSegment.NavigationProperty.Name);
                    e = Expression.MakeMemberAccess(parameter, navigationClrProperty);

                    MethodInfo selectMethodInfo;
                    selectType = OeExpressionHelper.GetCollectionItemType(e.Type);
                    if (selectType == null)
                    {
                        selectType       = e.Type;
                        selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceItemType, selectType);
                    }
                    else
                    {
                        selectMethodInfo = OeMethodInfoHelper.GetSelectManyMethodInfo(sourceItemType, selectType);
                    }

                    LambdaExpression lambda = Expression.Lambda(e, parameter);
                    source = Expression.Call(selectMethodInfo, source, lambda);
                }

                if (parseNavigationSegment.Filter != null)
                {
                    var visitor = new OeQueryNodeVisitor(Visitor, Expression.Parameter(selectType));
                    e = visitor.TranslateNode(parseNavigationSegment.Filter.Expression);
                    LambdaExpression lambda = Expression.Lambda(e, visitor.Parameter);

                    MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(selectType);
                    source = Expression.Call(whereMethodInfo, source, lambda);
                }

                sourceItemType = selectType;
            }

            Visitor.ChangeParameterType(Expression.Parameter(sourceItemType));
            return(source);
        }
        public Expression ApplySkipToken(Expression source, OeSkipTokenNameValue[] skipTokenNameValues, OrderByClause uniqueOrderBy, bool isDatabaseNullHighestValue)
        {
            if (skipTokenNameValues == null || skipTokenNameValues.Length == 0)
            {
                return(source);
            }

            var skipTokenTranslator = new Translators.OeSkipTokenTranslator(Visitor, _joinBuilder, isDatabaseNullHighestValue);

            source = skipTokenTranslator.Build(source, skipTokenNameValues, uniqueOrderBy);

            Visitor.ChangeParameterType(source);
            return(source);
        }