public override Expression Translate(PathSelectItem item)
        {
            _pathSelect = true;
            Expression expression;

            if (item.SelectedPath.LastSegment is NavigationPropertySegment)
            {
                var segment = (NavigationPropertySegment)item.SelectedPath.LastSegment;
                expression = Translate(segment, null);
            }
            else if (item.SelectedPath.LastSegment is PropertySegment)
            {
                var segment = (PropertySegment)item.SelectedPath.LastSegment;
                _selectItemInfo = new SelectItemInfo(null, segment.Property, null, null);

                PropertyInfo property = _parameter.Type.GetTypeInfo().GetProperty(segment.Property.Name);
                expression = Expression.MakeMemberAccess(_parameter, property);
            }
            else
            {
                throw new InvalidOperationException(item.SelectedPath.LastSegment.GetType().Name + " not supported");
            }

            return(expression);
        }
        private List <OeEntryFactory> GetNavigationLinks(IReadOnlyList <MemberExpression> itemExpressions, ParameterExpression parameter)
        {
            var navigationLinks = new List <OeEntryFactory>(_selectItemInfos.Count);

            for (int i = 0; i < _selectItemInfos.Count; i++)
            {
                SelectItemInfo itemInfo = _selectItemInfos[i];
                if (itemInfo.EdmProperty is IEdmNavigationProperty)
                {
                    MemberExpression expression = itemExpressions[_pathSelect ? i : i + 1];

                    OeEntryFactory entryFactory;
                    if (itemInfo.EntryFactory == null)
                    {
                        Type type = expression.Type;
                        if (itemInfo.ResourceInfo.IsCollection.GetValueOrDefault())
                        {
                            type = OeExpressionHelper.GetCollectionItemType(type);
                        }

                        OePropertyAccessor[] accessors = OePropertyAccessor.CreateFromType(type, itemInfo.EntitySet);
                        entryFactory             = OeEntryFactory.CreateEntryFactoryChild(itemInfo.EntitySet, accessors, itemInfo.ResourceInfo);
                        entryFactory.CountOption = itemInfo.CountOption;
                    }
                    else
                    {
                        entryFactory = itemInfo.EntryFactory;
                    }
                    entryFactory.LinkAccessor = (Func <Object, Object>)Expression.Lambda(expression, parameter).Compile();

                    navigationLinks.Add(entryFactory);
                }
            }
            return(navigationLinks);
        }
        private OeEntryFactory CreateNestedEntryFactory(Type sourceType, IEdmEntitySet entitySet, ODataNestedResourceInfo resourceInfo)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(Object));
            IReadOnlyList <MemberExpression> itemExpressions = OeExpressionHelper.GetPropertyExpression(Expression.Convert(parameter, sourceType));

            List <OeEntryFactory> navigationLinks = GetNavigationLinks(itemExpressions, parameter);

            OePropertyAccessor[] accessors;
            if (_pathSelect)
            {
                var accessorsList = new List <OePropertyAccessor>(_selectItemInfos.Count);
                for (int i = 0; i < _selectItemInfos.Count; i++)
                {
                    SelectItemInfo info = _selectItemInfos[i];
                    if (info.EdmProperty is IEdmStructuralProperty)
                    {
                        accessorsList.Add(OePropertyAccessor.CreatePropertyAccessor(info.EdmProperty, itemExpressions[i], parameter));
                    }
                }
                accessors = accessorsList.ToArray();
            }
            else
            {
                accessors = OePropertyAccessor.CreateFromExpression(itemExpressions[0], parameter, entitySet);
            }

            return(OeEntryFactory.CreateEntryFactoryNested(entitySet, accessors, resourceInfo, navigationLinks));
        }
        public OeEntryFactory CreateEntryFactory(Type entityType, IEdmEntitySetBase entitySet, Type sourceType)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(Object));
            IReadOnlyList <MemberExpression> itemExpressions = OeExpressionHelper.GetPropertyExpression(Expression.Convert(parameter, sourceType));

            OeEntryFactory        entryFactory;
            List <OeEntryFactory> navigationLinks = GetNavigationLinks(itemExpressions, parameter);

            if (_pathSelect)
            {
                var accessors = new List <OePropertyAccessor>(_selectItemInfos.Count);
                for (int i = 0; i < _selectItemInfos.Count; i++)
                {
                    SelectItemInfo info = _selectItemInfos[i];
                    if (info.EdmProperty is IEdmStructuralProperty)
                    {
                        accessors.Add(OePropertyAccessor.CreatePropertyAccessor(info.EdmProperty, itemExpressions[i], parameter));
                    }
                }
                entryFactory = OeEntryFactory.CreateEntryFactoryParent(entitySet, accessors.ToArray(), navigationLinks);
            }
            else
            {
                OePropertyAccessor[] accessors = OePropertyAccessor.CreateFromType(entityType, entitySet);
                entryFactory = OeEntryFactory.CreateEntryFactoryParent(entitySet, accessors, navigationLinks);
                entryFactory.LinkAccessor = (Func <Object, Object>)Expression.Lambda(itemExpressions[0], parameter).Compile();
            }
            return(entryFactory);
        }
        private void BuildSelect(SelectExpandClause selectClause, Expression source, ParameterExpression parameter,
                                 OeMetadataLevel metadataLevel, bool navigationNextLink)
        {
            foreach (SelectItem selectItem in selectClause.SelectedItems)
            {
                var            selectItemTranslator = new SelectItemTranslator(_visitor, _path, metadataLevel, navigationNextLink, parameter, source);
                SelectItemInfo selectItemInfo       = selectItem.TranslateWith(selectItemTranslator);
                if (selectItemInfo == null || SelectItemInfoExists(selectItemInfo.EdmProperty))
                {
                    continue;
                }

                _selectItemInfos.Add(selectItemInfo);
            }

            if (_selectItemInfos.Any(i => i.PropertySelect))
            {
                if (metadataLevel == OeMetadataLevel.Full)
                {
                    AddKey(parameter);
                }
            }
            else
            {
                _selectItemInfos.Insert(0, new SelectItemInfo(parameter));
            }
        }
        private Expression Translate(NavigationPropertySegment segment, bool?countOption)
        {
            IEdmNavigationProperty navigationEdmProperty = segment.NavigationProperty;
            var collectionType = navigationEdmProperty.Type.Definition as IEdmCollectionType;

            var resourceInfo = new ODataNestedResourceInfo()
            {
                IsCollection = collectionType != null,
                Name         = navigationEdmProperty.Name
            };

            var entitySet = (IEdmEntitySet)segment.NavigationSource;

            if (entitySet == null)
            {
                IEdmType entityType;
                if (collectionType == null)
                {
                    entityType = navigationEdmProperty.Type.Definition;
                }
                else
                {
                    entityType = collectionType.ElementType.Definition;
                }
                foreach (IEdmEntitySet element in _model.EntityContainer.Elements)
                {
                    if (element.EntityType() == entityType)
                    {
                        entitySet = element;
                        break;
                    }
                }
            }
            _selectItemInfo = new SelectItemInfo(entitySet, navigationEdmProperty, resourceInfo, countOption);

            PropertyInfo navigationClrProperty = _parameter.Type.GetTypeInfo().GetProperty(navigationEdmProperty.Name);

            return(Expression.MakeMemberAccess(_parameter, navigationClrProperty));
        }