/// <summary>
        /// Constructs a CollectionNavigationNode.
        /// </summary>
        /// <param name="navigationSource">The navigation source that this of the previous segment.</param>
        /// <param name="navigationProperty">The navigation property this node represents.</param>
        /// <param name="parsedSegments">The path segments parsed in path and query option.</param>
        private CollectionNavigationNode(IEdmNavigationSource navigationSource, IEdmNavigationProperty navigationProperty, List <ODataPathSegment> parsedSegments)
            : this(navigationProperty)
        {
            this.parsedSegments = parsedSegments;

            this.navigationSource = navigationSource != null?navigationSource.FindNavigationTarget(navigationProperty, BindingPathHelper.MatchBindingPath, this.parsedSegments, out this.bindingPath) : null;
        }
Example #2
0
        internal static IEdmEntitySetBase GetTargetEntitySet(this IEdmOperation operation, IEdmNavigationSource source, IEdmModel model)
        {
            if (source == null)
            {
                return(null);
            }

            if (operation.IsBound && operation.Parameters.Any())
            {
                IEdmOperationParameter parameter;
                Dictionary <IEdmNavigationProperty, IEdmPathExpression> path;
                IEdmEntityType lastEntityType;

                if (operation.TryGetRelativeEntitySetPath(model, out parameter, out path, out lastEntityType, out IEnumerable <EdmError> _))
                {
                    IEdmNavigationSource target = source;

                    foreach (var navigation in path)
                    {
                        target = target.FindNavigationTarget(navigation.Key, navigation.Value);
                    }

                    return(target as IEdmEntitySetBase);
                }
            }

            return(null);
        }
Example #3
0
        /// <summary>
        /// Find the navigation target which is <paramref name="navigationProperty"/> of current <paramref name="navigationSource"/> targets.
        /// The function is specifically used in Uri parser.
        /// </summary>
        /// <param name="navigationSource">The navigation source to find.</param>
        /// <param name="navigationProperty">The navigation property</param>
        /// <param name="matchBindingPath">The function used to determine if the binding path matches.</param>
        /// <param name="parsedSegments">The parsed segments in path, which is used to match binding path.</param>
        /// <param name="bindingPath">The output binding path of the navigation property which matches the <paramref name="parsedSegments"/></param>
        /// <returns>The navigation target which matches the binding path.</returns>
        public static IEdmNavigationSource FindNavigationTarget(this IEdmNavigationSource navigationSource, IEdmNavigationProperty navigationProperty, Func <IEdmPathExpression, IList <ODataPathSegment>, bool> matchBindingPath, IList <ODataPathSegment> parsedSegments, out IEdmPathExpression bindingPath)
        {
            Debug.Assert(navigationSource != null);
            Debug.Assert(navigationProperty != null);
            Debug.Assert(matchBindingPath != null);
            Debug.Assert(parsedSegments != null);

            bindingPath = null;

            if (navigationProperty.ContainsTarget)
            {
                return(navigationSource.FindNavigationTarget(navigationProperty));
            }

            IEnumerable <IEdmNavigationPropertyBinding> bindings = navigationSource.FindNavigationPropertyBindings(navigationProperty);

            if (bindings != null)
            {
                foreach (var binding in bindings)
                {
                    if (matchBindingPath(binding.Path, parsedSegments))
                    {
                        bindingPath = binding.Path;
                        return(binding.Target);
                    }
                }
            }

            return(new UnknownEntitySet(navigationSource, navigationProperty));
        }
Example #4
0
        private static void SnapExpandedEntry(List <DeltaSnapshotEntry> results, object element, IEdmNavigationSource edmParent, IEnumerable <ExpandedNavigationSelectItem> expandedNavigationItems, string parentId)
        {
            foreach (var navigationProperty in ((IEdmEntityType)EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, element)).NavigationProperties())
            {
                var expandedNavigationItem = GetExpandedNavigationItem(expandedNavigationItems, navigationProperty.Name);

                if (expandedNavigationItem != null)
                {
                    bool isCollection = navigationProperty.Type.IsCollection();

                    ExpandSelectItemHandler expandItemHandler = new ExpandSelectItemHandler(element);
                    expandedNavigationItem.HandleWith(expandItemHandler);
                    var propertyValue = expandItemHandler.ExpandedChildElement;

                    if (propertyValue != null)
                    {
                        IEdmNavigationSource targetSource = edmParent.FindNavigationTarget(navigationProperty);

                        if (isCollection)
                        {
                            SnapResults(results, propertyValue as IEnumerable, targetSource as IEdmEntitySetBase, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                        }
                        else
                        {
                            SnapResult(results, propertyValue, targetSource, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                        }
                    }
                }
            }
        }
Example #5
0
        private static void SnapExpandedEntry(List<DeltaSnapshotEntry> results, object element, IEdmNavigationSource edmParent, IEnumerable<ExpandedNavigationSelectItem> expandedNavigationItems, string parentId)
        {
            foreach (var navigationProperty in ((IEdmEntityType)EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, element)).NavigationProperties())
            {
                var expandedNavigationItem = GetExpandedNavigationItem(expandedNavigationItems, navigationProperty.Name);

                if (expandedNavigationItem != null)
                {
                    bool isCollection = navigationProperty.Type.IsCollection();

                    ExpandSelectItemHandler expandItemHandler = new ExpandSelectItemHandler(element);
                    expandedNavigationItem.HandleWith(expandItemHandler);
                    var propertyValue = expandItemHandler.ExpandedChildElement;

                    if (propertyValue != null)
                    {
                        IEdmNavigationSource targetSource = edmParent.FindNavigationTarget(navigationProperty);

                        if (isCollection)
                        {
                            SnapResults(results, propertyValue as IEnumerable, targetSource as IEdmEntitySetBase, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                        }
                        else
                        {
                            SnapResult(results, propertyValue, targetSource, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                        }
                    }

                }
            }
        }
Example #6
0
        private static IEnumerable <SelectItem> GetAutoExpandedNavigationSelectItems(
            IEdmEntityType baseEntityType,
            IEdmModel model,
            string alreadyExpandedNavigationSourceName,
            IEdmNavigationSource navigationSource,
            bool isAllSelected,
            bool searchDerivedTypeWhenAutoExpand)
        {
            var expandItems = new List <SelectItem>();
            var autoExpandNavigationProperties = EdmLibHelpers.GetAutoExpandNavigationProperties(baseEntityType, model,
                                                                                                 searchDerivedTypeWhenAutoExpand);

            foreach (var navigationProperty in autoExpandNavigationProperties)
            {
                if (!alreadyExpandedNavigationSourceName.Equals(navigationProperty.Name))
                {
                    IEdmEntityType       entityType = navigationProperty.DeclaringEntityType();
                    IEdmNavigationSource currentEdmNavigationSource =
                        navigationSource.FindNavigationTarget(navigationProperty);

                    if (currentEdmNavigationSource != null)
                    {
                        List <ODataPathSegment> pathSegments = new List <ODataPathSegment>()
                        {
                            new NavigationPropertySegment(navigationProperty, currentEdmNavigationSource)
                        };

                        ODataExpandPath    expandPath         = new ODataExpandPath(pathSegments);
                        SelectExpandClause selectExpandClause = new SelectExpandClause(new List <SelectItem>(),
                                                                                       true);
                        ExpandedNavigationSelectItem item = new ExpandedNavigationSelectItem(expandPath,
                                                                                             currentEdmNavigationSource, selectExpandClause);
                        if (!currentEdmNavigationSource.EntityType().Equals(entityType))
                        {
                            IEnumerable <SelectItem> nestedSelectItems = GetAutoExpandedNavigationSelectItems(
                                currentEdmNavigationSource.EntityType(),
                                model,
                                alreadyExpandedNavigationSourceName,
                                item.NavigationSource,
                                true,
                                searchDerivedTypeWhenAutoExpand);
                            selectExpandClause = new SelectExpandClause(nestedSelectItems, true);
                            item = new ExpandedNavigationSelectItem(expandPath, currentEdmNavigationSource,
                                                                    selectExpandClause);
                        }

                        expandItems.Add(item);
                        if (!isAllSelected)
                        {
                            PathSelectItem pathSelectItem = new PathSelectItem(
                                new ODataSelectPath(pathSegments));
                            expandItems.Add(pathSelectItem);
                        }
                    }
                }
            }
            return(expandItems);
        }
Example #7
0
        private static void WriteNavigationLinks(ODataWriter writer, object element, Uri parentEntryUri, IEdmNavigationSource edmParent, ODataVersion targetVersion, IEnumerable <ExpandedNavigationSelectItem> expandedNavigationItems)
        {
            foreach (var navigationProperty in ((IEdmEntityType)EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, element)).NavigationProperties())
            {
                var expandedNavigationItem = GetExpandedNavigationItem(expandedNavigationItems, navigationProperty.Name);

                // For Atom, we always manually write out the links for the navigation properties off of the entity type
                // Or if the navigation is expanded, we manually write out the links for the navigation properties along with the expanded entries
                if (writer.GetType().Name != "ODataJsonLightWriter" || expandedNavigationItem != null)
                {
                    bool isCollection = navigationProperty.Type.IsCollection();

                    var navigationLink = new ODataNavigationLink
                    {
                        IsCollection = isCollection,
                        Name         = navigationProperty.Name,
                    };

                    if (writer.GetType().Name == "ODataAtomWriter")
                    {
                        //If the passed in parentEntryUri is null then exception will be thrown, to avoid this, create a relative 'potato' Uri.
                        navigationLink.Url = (parentEntryUri == null) ? new Uri("potato", UriKind.Relative) : new Uri(new Uri(parentEntryUri.AbsoluteUri + "/"), navigationProperty.Name);
                    }

                    writer.WriteStart(navigationLink);

                    if (expandedNavigationItem != null)
                    {
                        ExpandSelectItemHandler expandItemHandler = new ExpandSelectItemHandler(element);
                        expandedNavigationItem.HandleWith(expandItemHandler);
                        var propertyValue = expandItemHandler.ExpandedChildElement;

                        if (propertyValue != null)
                        {
                            IEdmNavigationSource targetSource = edmParent.FindNavigationTarget(navigationProperty);

                            if (isCollection)
                            {
                                long?count           = null;
                                var  collectionValue = propertyValue as IEnumerable;
                                if (collectionValue != null && expandedNavigationItem.CountOption == true)
                                {
                                    count = collectionValue.Cast <object>().LongCount();
                                }
                                WriteFeed(writer, collectionValue, targetSource as IEdmEntitySetBase, targetVersion, expandedNavigationItem.SelectAndExpand, count, null, null);
                            }
                            else
                            {
                                WriteEntry(writer, propertyValue, targetSource, targetVersion, expandedNavigationItem.SelectAndExpand);
                            }
                        }
                    }

                    writer.WriteEnd();
                }
            }
        }
Example #8
0
        /// <inheritdoc/>
        public override IEdmNavigationSource GetNavigationSource(IEdmNavigationSource previousNavigationSource)
        {
            if (NavigationProperty != null && previousNavigationSource != null)
            {
                return(previousNavigationSource.FindNavigationTarget(NavigationProperty));
            }

            return(null);
        }
        /// <inheritdoc/>
        public override IEdmNavigationSource GetNavigationSource(IEdmNavigationSource previousNavigationSource)
        {
            if (_edmModel == null)
            {
                return(null);
            }

            // Try to use the entity set annotation to get the target navigation source.
            ReturnedEntitySetAnnotation entitySetAnnotation =
                _edmModel.GetAnnotationValue <ReturnedEntitySetAnnotation>(Function);

            if (entitySetAnnotation != null)
            {
                return(_edmModel.EntityContainer.FindEntitySet(entitySetAnnotation.EntitySetName));
            }

            // Try to use the entity set path to get the target navigation source.
            // An entity set path is a string list seperated by '/', for example "bindingParameter/Orders".
            // The first segment must be the binding parameter name, while the orthers must be the navigation property
            // name. ODL can use the entity set path expression and the bound navigation source to calucate the target
            // navigation source. for example:
            // ~/CustomersA(1)/GetRelatedOrders() will return OrdersA
            // ~/CustomersB(1)/GetRelatedOrders() will return OrdersB
            if (previousNavigationSource != null && _edmModel != null && Function != null)
            {
                IEdmOperationParameter parameter;
                IEnumerable <IEdmNavigationProperty> navigationProperties;
                IEdmEntityType         lastEntityType;
                IEnumerable <EdmError> errors;

                if (Function.TryGetRelativeEntitySetPath(_edmModel, out parameter, out navigationProperties,
                                                         out lastEntityType, out errors))
                {
                    IEdmNavigationSource targetNavigationSource = previousNavigationSource;
                    foreach (IEdmNavigationProperty navigationProperty in navigationProperties)
                    {
                        targetNavigationSource = targetNavigationSource.FindNavigationTarget(navigationProperty);
                        if (targetNavigationSource == null)
                        {
                            return(null);
                        }
                    }

                    return(targetNavigationSource);
                }
            }

            return(null);
        }
Example #10
0
        private void AddSelector(string httpMethod, ODataControllerActionContext context, ActionModel action,
                                 IEdmNavigationSource navigationSource, string declared, IEdmEntityType declaringEntityType,
                                 IEdmNavigationProperty navigationProperty, bool hasKey, bool dollarCount)
        {
            IEdmEntitySet  entitySet  = navigationSource as IEdmEntitySet;
            IEdmEntityType entityType = navigationSource.EntityType();

            // Starts the routing template
            IList <ODataSegmentTemplate> segments = new List <ODataSegmentTemplate>();

            if (entitySet != null)
            {
                segments.Add(new EntitySetSegmentTemplate(entitySet));
            }
            else
            {
                segments.Add(new SingletonSegmentTemplate(navigationSource as IEdmSingleton));
            }

            if (hasKey)
            {
                segments.Add(KeySegmentTemplate.CreateKeySegment(entityType, navigationSource));
            }

            if (declared != null)
            {
                // It should be always single type
                if (entityType != declaringEntityType)
                {
                    segments.Add(new CastSegmentTemplate(declaringEntityType, entityType, navigationSource));
                }
            }

            IEdmNavigationSource targetNavigationSource = navigationSource.FindNavigationTarget(navigationProperty, segments, out _);

            segments.Add(new NavigationSegmentTemplate(navigationProperty, targetNavigationSource));

            if (dollarCount)
            {
                segments.Add(CountSegmentTemplate.Instance);
            }

            ODataPathTemplate template = new ODataPathTemplate(segments);

            action.AddSelector(httpMethod.NormalizeHttpMethod(), context.Prefix, context.Model, template, context.RouteOptions);

            Log.AddedODataSelector(_logger, action, template);
        }
Example #11
0
        /// <summary>
        /// Constructs a SingleNavigationNode.
        /// </summary>
        /// <param name="navigationProperty">The navigation property this node represents.</param>
        /// <param name="sourceNavigationSource">The navigation source that this of the previous segment.</param>
        /// <exception cref="System.ArgumentNullException">Throws if the input navigationProperty or source is null.</exception>
        /// <exception cref="ArgumentException">Throws if the input navigationProperty targets more than one entity.</exception>
        public SingleNavigationNode(IEdmNavigationProperty navigationProperty, IEdmNavigationSource sourceNavigationSource)
        {
            ExceptionUtils.CheckArgumentNotNull(navigationProperty, "navigationProperty");

            EdmMultiplicity multiplicity = navigationProperty.TargetMultiplicityTemporary();

            if (multiplicity != EdmMultiplicity.One && multiplicity != EdmMultiplicity.ZeroOrOne)
            {
                throw new ArgumentException(ODataErrorStrings.Nodes_CollectionNavigationNode_MustHaveSingleMultiplicity);
            }

            this.navigationProperty  = navigationProperty;
            this.entityTypeReference = (IEdmEntityTypeReference)this.NavigationProperty.Type;

            this.navigationSource = sourceNavigationSource != null?sourceNavigationSource.FindNavigationTarget(navigationProperty) : null;
        }
Example #12
0
        /// <summary>
        /// Constructs a SingleNavigationNode.
        /// </summary>
        /// <param name="navigationSource">The navigation source that this of the previous segment.</param>
        /// <param name="navigationProperty">The navigation property this node represents.</param>
        /// <param name="bindingPath">The binding path of navigation property</param>
        /// <exception cref="System.ArgumentNullException">Throws if the input navigationProperty.</exception>
        /// <exception cref="ArgumentException">Throws if the input navigationProperty targets more than one entity.</exception>
        internal SingleNavigationNode(IEdmNavigationSource navigationSource, IEdmNavigationProperty navigationProperty, IEdmPathExpression bindingPath)
        {
            ExceptionUtils.CheckArgumentNotNull(navigationProperty, "navigationProperty");

            EdmMultiplicity multiplicity = navigationProperty.TargetMultiplicity();

            if (multiplicity != EdmMultiplicity.One && multiplicity != EdmMultiplicity.ZeroOrOne)
            {
                throw new ArgumentException(ODataErrorStrings.Nodes_CollectionNavigationNode_MustHaveSingleMultiplicity);
            }

            this.navigationProperty  = navigationProperty;
            this.entityTypeReference = (IEdmEntityTypeReference)this.NavigationProperty.Type;
            this.bindingPath         = bindingPath;
            this.navigationSource    = navigationSource != null?navigationSource.FindNavigationTarget(navigationProperty, bindingPath) : null;
        }
Example #13
0
        /// <summary>
        /// Constructs a SingleNavigationNode.
        /// </summary>
        /// <param name="navigationSource">The navigation source that this of the previous segment.</param>
        /// <param name="navigationProperty">The navigation property this node represents.</param>
        /// <param name="segments">The path segments parsed in path and query option.</param>
        private SingleNavigationNode(IEdmNavigationSource navigationSource,
                                     IEdmNavigationProperty navigationProperty, List <ODataPathSegment> segments)
        {
            ExceptionUtils.CheckArgumentNotNull(navigationProperty, "navigationProperty");

            EdmMultiplicity multiplicity = navigationProperty.TargetMultiplicity();

            if (multiplicity != EdmMultiplicity.One && multiplicity != EdmMultiplicity.ZeroOrOne)
            {
                throw new ArgumentException(ODataErrorStrings.Nodes_CollectionNavigationNode_MustHaveSingleMultiplicity);
            }

            this.navigationProperty  = navigationProperty;
            this.entityTypeReference = (IEdmEntityTypeReference)this.NavigationProperty.Type;
            this.parsedSegments      = segments;
            this.navigationSource    = navigationSource != null?navigationSource.FindNavigationTarget(navigationProperty, BindingPathHelper.MatchBindingPath, this.parsedSegments, out this.bindingPath) : null;
        }
Example #14
0
        /// <inheritdoc/>
        public override IEdmNavigationSource GetNavigationSource(IEdmNavigationSource previousNavigationSource)
        {
            if (_edmModel == null)
            {
                return(null);
            }

            // Try to use the entity set annotation to get the target navigation source.
            ReturnedEntitySetAnnotation entitySetAnnotation =
                _edmModel.GetAnnotationValue <ReturnedEntitySetAnnotation>(Action);

            if (entitySetAnnotation != null)
            {
                return(_edmModel.EntityContainer.FindEntitySet(entitySetAnnotation.EntitySetName));
            }

            // Try to use the entity set path to get the target navigation source.
            if (previousNavigationSource != null && Action != null)
            {
                IEdmOperationParameter parameter;
                IEnumerable <IEdmNavigationProperty> navigationProperties;
                IEdmEntityType         lastEntityType;
                IEnumerable <EdmError> errors;

                if (Action.TryGetRelativeEntitySetPath(_edmModel, out parameter, out navigationProperties,
                                                       out lastEntityType, out errors))
                {
                    IEdmNavigationSource targetNavigationSource = previousNavigationSource;
                    foreach (IEdmNavigationProperty navigationProperty in navigationProperties)
                    {
                        targetNavigationSource = targetNavigationSource.FindNavigationTarget(navigationProperty);
                        if (targetNavigationSource == null)
                        {
                            return(null);
                        }
                    }

                    return(targetNavigationSource);
                }
            }

            return(null);
        }
 public ODataUriParserInjectionTests()
 {
     folderType             = oneDriveModel.SchemaElements.OfType <IEdmComplexType>().Single(e => string.Equals(e.Name, "folder"));
     itemType               = oneDriveModel.SchemaElements.OfType <IEdmEntityType>().Single(e => string.Equals(e.Name, "item"));
     specialItemType        = oneDriveModel.SchemaElements.OfType <IEdmEntityType>().Single(e => string.Equals(e.Name, "specialItem"));
     folderProp             = itemType.FindProperty("folder") as IEdmStructuralProperty;
     sizeProp               = itemType.FindProperty("size") as IEdmStructuralProperty;
     driveType              = oneDriveModel.SchemaElements.OfType <IEdmEntityType>().Single(e => string.Equals(e.Name, "drive"));
     itemsNavProp           = driveType.DeclaredNavigationProperties().FirstOrDefault(p => p.Name == "items");
     childrenNavProp        = itemType.DeclaredNavigationProperties().FirstOrDefault(p => p.Name == "children");
     thumbnailsNavProp      = itemType.DeclaredNavigationProperties().FirstOrDefault(p => p.Name == "thumbnails");
     drivesEntitySet        = oneDriveModel.EntityContainer.FindEntitySet("drives");
     driveSingleton         = oneDriveModel.EntityContainer.FindSingleton("drive");
     containedItemsNav      = drivesEntitySet.FindNavigationTarget(itemsNavProp);
     containedthumbnailsNav = containedItemsNav.FindNavigationTarget(thumbnailsNavProp);
     copyOp   = oneDriveModel.SchemaElements.OfType <IEdmOperation>().FirstOrDefault(o => o.Name == "copy");
     searchOp = oneDriveModel.SchemaElements.OfType <IEdmOperation>().FirstOrDefault(o => o.Name == "search");
     shareItemBindCollectionOp = oneDriveModel.SchemaElements.OfType <IEdmOperation>().LastOrDefault(o => o.Name == "sharedWithMe");
 }
        /// <summary>
        /// Gets the target entity set for the given operation import.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <param name="source">The source of operation.</param>
        /// <param name="model">The model.</param>
        /// <returns>The target entity set of the operation import or null if it could not be determined.</returns>
        internal static IEdmEntitySetBase GetTargetEntitySet(this IEdmOperation operation, IEdmNavigationSource source, IEdmModel model)
        {
            if (source == null)
            {
                return(null);
            }

            if (operation.IsBound && operation.Parameters.Any())
            {
                IEdmOperationParameter parameter;
                IEnumerable <IEdmNavigationProperty> path;
                IEdmEntityType         lastEntityType;
                IEnumerable <EdmError> errors;

                if (operation.TryGetRelativeEntitySetPath(model, out parameter, out path, out lastEntityType, out errors))
                {
                    IEdmNavigationSource target = source;
                    foreach (var navigation in path)
                    {
                        target = target.FindNavigationTarget(navigation);
                        if (target == null)
                        {
                            return(null);
                        }
                    }

                    return(target as IEdmEntitySetBase);
                }
                else
                {
                    if (errors.Any(
                            e => e.ErrorCode == EdmErrorCode.InvalidPathFirstPathParameterNotMatchingFirstParameterName))
                    {
                        throw ExceptionUtil.CreateSyntaxError();
                    }
                }
            }

            return(null);
        }
Example #17
0
        /// <summary>
        /// Handle $expand
        /// </summary>
        /// <param name="entry">Entry</param>
        /// <param name="edmParent">Parent EntitySet</param>
        /// <param name="targetVersion">Target Version</param>
        /// <param name="expandedNavigationItems">Expand Items</param>
        /// <param name="parentId">Parent Id</param>
        private void GenerateDeltaItemsFromExpand(object entry, IEdmNavigationSource edmParent, ODataVersion targetVersion, IEnumerable <ExpandedNavigationSelectItem> expandedNavigationItems, string parentId)
        {
            foreach (var navigationProperty in ((IEdmEntityType)EdmClrTypeUtils.GetEdmType(this.DataSource.Model, entry)).NavigationProperties())
            {
                var expandedNavigationItem = GetExpandedNavigationItem(expandedNavigationItems, navigationProperty.Name);

                if (expandedNavigationItem != null)
                {
                    bool isCollection = navigationProperty.Type.IsCollection();

                    ExpandSelectItemHandler expandItemHandler = new ExpandSelectItemHandler(entry);
                    expandedNavigationItem.HandleWith(expandItemHandler);
                    var propertyValue = expandItemHandler.ExpandedChildElement;

                    if (propertyValue != null)
                    {
                        IEdmNavigationSource targetSource = edmParent.FindNavigationTarget(navigationProperty);

                        if (isCollection)
                        {
                            var expandedEntities = propertyValue as IEnumerable;
                            foreach (var expandedEntity in expandedEntities)
                            {
                                GenerateDeltaItemFromEntry(expandedEntity, targetSource, targetVersion, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                            }
                        }
                        else
                        {
                            GenerateDeltaItemFromEntry(propertyValue, targetSource, targetVersion, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                        }
                    }

                    // Handle deleted entry and link here
                    GenerateDeltaItemsFromDeletedEntities(parentId, navigationProperty.Name);
                }
            }
        }
Example #18
0
 /// <summary>
 /// Creates a CollectionNavigationNode.
 /// </summary>
 /// <param name="navigationProperty">The navigation property that defines the collection node.</param>
 /// <param name="source">The navigation source.</param>
 /// <returns>The collection node.</returns>
 /// <exception cref="System.ArgumentNullException">Throws if the input navigation property is null.</exception>
 /// <exception cref="ArgumentException">Throws if the input navigation doesn't target a collection.</exception>
 public CollectionNavigationNode(IEdmNavigationProperty navigationProperty, IEdmNavigationSource source)
     : this(navigationProperty)
 {
     this.navigationSource = source != null?source.FindNavigationTarget(navigationProperty) : null;
 }
Example #19
0
        private void GetAutoSelectExpandItems(
            IEdmEntityType baseEntityType,
            IEdmModel model,
            IEdmNavigationSource navigationSource,
            bool isAllSelected,
            ModelBoundQuerySettings modelBoundQuerySettings,
            int depth,
            out List <SelectItem> autoSelectItems,
            out List <SelectItem> autoExpandItems)
        {
            autoSelectItems = new List <SelectItem>();
            var autoSelectProperties = EdmLibHelpers.GetAutoSelectProperties(null,
                                                                             baseEntityType, model, modelBoundQuerySettings);

            foreach (var autoSelectProperty in autoSelectProperties)
            {
                List <ODataPathSegment> pathSegments = new List <ODataPathSegment>()
                {
                    new PropertySegment(autoSelectProperty)
                };

                PathSelectItem pathSelectItem = new PathSelectItem(
                    new ODataSelectPath(pathSegments));
                autoSelectItems.Add(pathSelectItem);
            }

            autoExpandItems = new List <SelectItem>();
            depth--;
            if (depth < 0)
            {
                return;
            }

            var autoExpandNavigationProperties = EdmLibHelpers.GetAutoExpandNavigationProperties(null, baseEntityType,
                                                                                                 model, !isAllSelected, modelBoundQuerySettings);

            foreach (var navigationProperty in autoExpandNavigationProperties)
            {
                IEdmNavigationSource currentEdmNavigationSource =
                    navigationSource.FindNavigationTarget(navigationProperty);

                if (currentEdmNavigationSource != null)
                {
                    List <ODataPathSegment> pathSegments = new List <ODataPathSegment>()
                    {
                        new NavigationPropertySegment(navigationProperty, currentEdmNavigationSource)
                    };

                    ODataExpandPath    expandPath         = new ODataExpandPath(pathSegments);
                    SelectExpandClause selectExpandClause = new SelectExpandClause(new List <SelectItem>(),
                                                                                   true);
                    ExpandedNavigationSelectItem item = new ExpandedNavigationSelectItem(expandPath,
                                                                                         currentEdmNavigationSource, selectExpandClause);
                    modelBoundQuerySettings = EdmLibHelpers.GetModelBoundQuerySettings(navigationProperty,
                                                                                       navigationProperty.ToEntityType(), model);
                    List <SelectItem> nestedSelectItems;
                    List <SelectItem> nestedExpandItems;

                    int maxExpandDepth = GetMaxExpandDepth(modelBoundQuerySettings, navigationProperty.Name);
                    if (maxExpandDepth != 0 && maxExpandDepth < depth)
                    {
                        depth = maxExpandDepth;
                    }

                    GetAutoSelectExpandItems(
                        currentEdmNavigationSource.EntityType(),
                        model,
                        item.NavigationSource,
                        true,
                        modelBoundQuerySettings,
                        depth,
                        out nestedSelectItems,
                        out nestedExpandItems);

                    selectExpandClause = new SelectExpandClause(nestedSelectItems.Concat(nestedExpandItems),
                                                                nestedSelectItems.Count == 0);
                    item = new ExpandedNavigationSelectItem(expandPath, currentEdmNavigationSource,
                                                            selectExpandClause);

                    autoExpandItems.Add(item);
                    if (!isAllSelected || autoSelectProperties.Count() != 0)
                    {
                        PathSelectItem pathSelectItem = new PathSelectItem(
                            new ODataSelectPath(pathSegments));
                        autoExpandItems.Add(pathSelectItem);
                    }
                }
            }
        }
Example #20
0
        /// <inheritdoc />
        public bool AppliesToAction(ODataControllerActionContext context)
        {
            if (context == null)
            {
                throw Error.ArgumentNull(nameof(context));
            }

            Debug.Assert(context.Action != null);

            ActionModel action           = context.Action;
            string      actionMethodName = action.ActionName;

            // Need to refactor the following
            // for example:  CreateRef( with the navigation property parameter) should for all navigation properties
            // CreateRefToOrdersFromCustomer, CreateRefToOrders, CreateRef.
            string method = SplitRefActionName(actionMethodName, out string httpMethod, out string property, out string declaring);

            if (method == null)
            {
                return(false);
            }

            IEdmNavigationSource navigationSource = context.NavigationSource;
            IEdmEntityType       entityType       = context.EntityType;

            // For entity set, we should have the key parameter
            // For Singleton, we should not have the key parameter
            bool hasODataKeyParameter = action.HasODataKeyParameter(entityType);

            if ((context.EntitySet != null && !hasODataKeyParameter) ||
                (context.Singleton != null && hasODataKeyParameter))
            {
                return(false);
            }

            // Find the navigation property declaring type
            IEdmStructuredType declaringType = entityType;

            if (declaring != null)
            {
                declaringType = entityType.FindTypeInInheritance(context.Model, declaring);
                if (declaringType == null)
                {
                    return(false);
                }
            }

            // Process the generic scenario
            if (property == null)
            {
                return(ProcessNonNavigationProperty(httpMethod, context, action, navigationSource, entityType, declaringType));
            }

            // Find the navigation property if have
            IEdmNavigationProperty navigationProperty = null;

            if (property != null)
            {
                navigationProperty = declaringType.DeclaredNavigationProperties().FirstOrDefault(p => p.Name == property);
            }

            if (navigationProperty == null)
            {
                return(false);
            }

            IList <ODataSegmentTemplate> segments = new List <ODataSegmentTemplate>();

            if (context.EntitySet != null)
            {
                segments.Add(new EntitySetSegmentTemplate(context.EntitySet));
                segments.Add(KeySegmentTemplate.CreateKeySegment(entityType, context.EntitySet));
            }
            else
            {
                segments.Add(new SingletonSegmentTemplate(context.Singleton));
            }

            if (entityType != declaringType)
            {
                segments.Add(new CastSegmentTemplate(declaringType, entityType, navigationSource));
            }

            IEdmNavigationSource          targetNavigationSource = navigationSource.FindNavigationTarget(navigationProperty, segments, out _);
            NavigationLinkSegmentTemplate linkTemplate           = new NavigationLinkSegmentTemplate(navigationProperty, targetNavigationSource);

            IEdmEntityType navigationPropertyType            = navigationProperty.Type.GetElementTypeOrSelf().AsEntity().EntityDefinition();
            bool           hasNavigationPropertyKeyParameter = action.HasODataKeyParameter(navigationPropertyType, "relatedKey");

            if (hasNavigationPropertyKeyParameter)
            {
                linkTemplate.Key = KeySegmentTemplate.CreateKeySegment(navigationPropertyType, targetNavigationSource, "relatedKey");
            }
            else
            {
                hasNavigationPropertyKeyParameter = action.HasODataKeyParameter(navigationPropertyType, "relatedId");
                if (hasNavigationPropertyKeyParameter)
                {
                    linkTemplate.Key = KeySegmentTemplate.CreateKeySegment(navigationPropertyType, targetNavigationSource, "relatedId");
                }
            }

            segments.Add(linkTemplate);

            ODataPathTemplate template = new ODataPathTemplate(segments);

            action.AddSelector(httpMethod, context.Prefix, context.Model, template, context.Options?.RouteOptions);

            // processed
            return(true);
        }
        private void FillStockContentsForEntityContainer(IEdmEntityContainer edmContainer, IEdmModel edmModel, EdmModel stockModel)
        {
            var stockContainer = (EdmEntityContainer)stockModel.FindEntityContainer(edmContainer.FullName());

            this.SetImmediateAnnotations(edmContainer, stockContainer, edmModel, stockModel);

            foreach (var edmNavigationSource in edmContainer.Elements.OfType <IEdmNavigationSource>())
            {
                var stockEntityType = (EdmEntityType)stockModel.FindType(GetFullName(edmNavigationSource.EntityType()));
                if (edmNavigationSource is IEdmSingleton)
                {
                    stockContainer.AddSingleton(edmNavigationSource.Name, stockEntityType);
                }
                else
                {
                    stockContainer.AddEntitySet(edmNavigationSource.Name, stockEntityType);
                }
            }

            foreach (var stockNavigationSource in stockContainer.Elements.OfType <EdmNavigationSource>())
            {
                var stockEntityType = (EdmEntityType)stockModel.FindType(GetFullName(stockNavigationSource.EntityType()));
                IEdmNavigationSource edmNavigationSource = edmContainer.FindEntitySet(stockNavigationSource.Name);
                if (edmNavigationSource == null)
                {
                    edmNavigationSource = edmContainer.FindSingleton(stockNavigationSource.Name);
                }

                var stockDerivedNavigations = GetAllNavigationFromDerivedTypesAndSelf(stockEntityType, stockModel);

                foreach (var stockNavigationProperty in stockDerivedNavigations)
                {
                    var edmNavigationProperty = edmNavigationSource.NavigationPropertyBindings.Select(n => n.NavigationProperty).SingleOrDefault(n => n.Name == stockNavigationProperty.Name);

                    if (edmNavigationProperty != null)
                    {
                        var targetEdmEntitySet = edmNavigationSource.FindNavigationTarget(edmNavigationProperty);

                        if (null != targetEdmEntitySet)
                        {
                            var targetEntitySetFromContainer = stockContainer.Elements.OfType <EdmEntitySet>().SingleOrDefault
                                                               (
                                n =>
                                GetBaseTypesAndSelf(((IEdmNavigationProperty)stockNavigationProperty).ToEntityType()).Select(m => GetFullName(m)).Contains(n.EntityType().FullName()) && n.Name == targetEdmEntitySet.Name
                                                               );

                            if (null == targetEntitySetFromContainer)
                            {
                                targetEntitySetFromContainer = stockContainer.Elements.OfType <EdmEntitySet>().SingleOrDefault
                                                               (
                                    n =>
                                    GetAllDerivedTypesAndSelf(((IEdmNavigationProperty)stockNavigationProperty).ToEntityType(), stockModel).Select(m => GetFullName(m)).Contains(n.EntityType().FullName()) && n.Name == targetEdmEntitySet.Name
                                                               );
                            }

                            stockNavigationSource.AddNavigationTarget(stockNavigationProperty, targetEntitySetFromContainer);
                        }
                    }
                }
            }

            foreach (var edmOperationImport in edmContainer.OperationImports())
            {
                EdmOperationImport stockEdmOperationImport = null;
                var edmActionImport = edmOperationImport as IEdmActionImport;

                if (edmActionImport != null)
                {
                    var newEdmAction = stockModel.FindDeclaredOperations(edmActionImport.Action.FullName()).OfType <IEdmAction>().FirstOrDefault() as EdmAction;
                    ExceptionUtilities.CheckObjectNotNull(newEdmAction, "cannot find action");
                    stockEdmOperationImport = stockContainer.AddActionImport(edmOperationImport.Name, newEdmAction, edmActionImport.EntitySet);
                }
                else
                {
                    IEdmFunctionImport edmFunctionImport = edmOperationImport as IEdmFunctionImport;
                    ExceptionUtilities.CheckArgumentNotNull(edmFunctionImport, "edmFunctionImport");

                    var newEdmFunction = edmModel.FindDeclaredOperations(edmFunctionImport.Function.FullName()).OfType <IEdmFunction>().FirstOrDefault();
                    ExceptionUtilities.CheckObjectNotNull(newEdmFunction, "Expected to find an function: " + edmFunctionImport.Function.FullName());
                    stockEdmOperationImport = stockContainer.AddFunctionImport(edmFunctionImport.Name, newEdmFunction, edmFunctionImport.EntitySet, edmFunctionImport.IncludeInServiceDocument);
                }

                this.SetImmediateAnnotations(edmOperationImport, stockEdmOperationImport, edmModel, stockModel);
            }
        }
 /// <summary>
 /// Creates a CollectionNavigationNode.
 /// </summary>
 /// <param name="navigationSource">The navigation source that this of the previous segment.</param>
 /// <param name="navigationProperty">The navigation property that defines the collection node.</param>
 /// <param name="bindingPath">The binding path of navigation property</param>
 /// <returns>The collection node.</returns>
 /// <exception cref="System.ArgumentNullException">Throws if the input navigation property is null.</exception>
 /// <exception cref="ArgumentException">Throws if the input navigation doesn't target a collection.</exception>
 internal CollectionNavigationNode(IEdmNavigationSource navigationSource, IEdmNavigationProperty navigationProperty, IEdmPathExpression bindingPath)
     : this(navigationProperty)
 {
     this.bindingPath      = bindingPath;
     this.navigationSource = navigationSource != null?navigationSource.FindNavigationTarget(navigationProperty, bindingPath) : null;
 }
Example #23
0
        private static void WriteNavigationLinks(ODataWriter writer, object element, Uri parentEntryUri, IEdmNavigationSource edmParent, ODataVersion targetVersion, IEnumerable<SelectItem> expandedItems)
        {
            foreach (var navigationProperty in ((IEdmEntityType)EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, element)).NavigationProperties())
            {
                // give proprity to ExpandedReferenceSelectItem
                var expandedItem = GetExpandedReferenceItem(expandedItems, navigationProperty.Name);
                if (expandedItem == null)
                {
                    expandedItem = GetExpandedNavigationItem(expandedItems, navigationProperty.Name);
                }

                // For Atom, we always manually write out the links for the navigation properties off of the entity type
                // Or if the navigation is expanded, we manually write out the links for the navigation properties along with the expanded entries
                if (writer.GetType().Name != "ODataJsonLightWriter" || expandedItem != null)
                {
                    bool isCollection = navigationProperty.Type.IsCollection();

                    var navigationLink = new ODataNavigationLink
                    {
                        IsCollection = isCollection,
                        Name = navigationProperty.Name,
                    };

                    if (writer.GetType().Name == "ODataAtomWriter")
                    {
                        //If the passed in parentEntryUri is null then exception will be thrown, to avoid this, create a relative 'potato' Uri.
                        navigationLink.Url = (parentEntryUri == null) ? new Uri("potato", UriKind.Relative) : new Uri(new Uri(parentEntryUri.AbsoluteUri + "/"), navigationProperty.Name);
                    }

                    writer.WriteStart(navigationLink);
                    if (expandedItem != null)
                    {
                        ExpandSelectItemHandler expandItemHandler = new ExpandSelectItemHandler(element);
                        expandedItem.HandleWith(expandItemHandler);

                        var propertyValue = expandItemHandler.ExpandedChildElement;

                        if (propertyValue != null)
                        {
                            IEdmNavigationSource targetSource = edmParent.FindNavigationTarget(navigationProperty);

                            if (isCollection)
                            {
                                long? count = null;
                                var collectionValue = propertyValue as IEnumerable;
                                if (collectionValue != null && expandedItem.CountOption == true)
                                {
                                    count = collectionValue.Cast<object>().LongCount();
                                }

                                if (expandedItem.GetType() == typeof(ExpandedReferenceSelectItem))
                                {
                                    WriteReferenceLinks(writer, collectionValue, targetSource as IEdmEntitySetBase, targetVersion, navigationLink);
                                }
                                else
                                {
                                    
                                    WriteFeed(writer, collectionValue, targetSource as IEdmEntitySetBase, targetVersion, ((ExpandedNavigationSelectItem)expandedItem).SelectAndExpand, count, null, null);
                                }
                            }
                            else
                            {
                                if (expandedItem.GetType() == typeof(ExpandedReferenceSelectItem))
                                {
                                    WriteReferenceLink(writer, propertyValue, targetSource, targetVersion, navigationLink);
                                }
                                else
                                {
                                    WriteEntry(writer, propertyValue, targetSource, targetVersion, ((ExpandedNavigationSelectItem)expandedItem).SelectAndExpand);                                   
                                }
                            }
                        }
                    }
                    writer.WriteEnd();
                }
            }
        }
Example #24
0
        /// <summary>
        /// Handle $expand
        /// </summary>
        /// <param name="entry">Entry</param>
        /// <param name="edmParent">Parent EntitySet</param>
        /// <param name="targetVersion">Target Version</param>
        /// <param name="expandedNavigationItems">Expand Items</param>
        /// <param name="parentId">Parent Id</param>
        private void GenerateDeltaItemsFromExpand(object entry, IEdmNavigationSource edmParent, ODataVersion targetVersion, IEnumerable<ExpandedNavigationSelectItem> expandedNavigationItems, string parentId)
        {
            foreach (var navigationProperty in ((IEdmEntityType)EdmClrTypeUtils.GetEdmType(this.DataSource.Model, entry)).NavigationProperties())
            {
                var expandedNavigationItem = GetExpandedNavigationItem(expandedNavigationItems, navigationProperty.Name);

                if (expandedNavigationItem != null)
                {
                    bool isCollection = navigationProperty.Type.IsCollection();

                    ExpandSelectItemHandler expandItemHandler = new ExpandSelectItemHandler(entry);
                    expandedNavigationItem.HandleWith(expandItemHandler);
                    var propertyValue = expandItemHandler.ExpandedChildElement;

                    if (propertyValue != null)
                    {
                        IEdmNavigationSource targetSource = edmParent.FindNavigationTarget(navigationProperty);

                        if (isCollection)
                        {
                            var expandedEntities = propertyValue as IEnumerable;
                            foreach (var expandedEntity in expandedEntities)
                            {
                                GenerateDeltaItemFromEntry(expandedEntity, targetSource, targetVersion, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                            }
                        }
                        else
                        {
                            GenerateDeltaItemFromEntry(propertyValue, targetSource, targetVersion, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                        }
                    }

                    // Handle deleted entry and link here
                    GenerateDeltaItemsFromDeletedEntities(parentId, navigationProperty.Name);
                }
            }
        }
Example #25
0
        /// <inheritdoc/>
        public override IEdmNavigationSource GetNavigationSource(IEdmNavigationSource previousNavigationSource)
        {
            if (NavigationProperty != null && previousNavigationSource != null)
            {
                return previousNavigationSource.FindNavigationTarget(NavigationProperty);
            }

            return null;
        }
Example #26
0
        private void GetAutoSelectExpandItems(IEdmEntityType baseEntityType, IEdmModel model, IEdmNavigationSource navigationSource, bool isAllSelected,
                                              ModelBoundQuerySettings modelBoundQuerySettings, int depth, out List <SelectItem> autoSelectItems, out List <SelectItem> autoExpandItems)
        {
            autoSelectItems = new List <SelectItem>();
            autoExpandItems = new List <SelectItem>();

            if (baseEntityType == null)
            {
                return;
            }

            IList <SelectModelPath> autoSelectProperties = model.GetAutoSelectPaths(baseEntityType, null, modelBoundQuerySettings);

            foreach (var autoSelectProperty in autoSelectProperties)
            {
                ODataSelectPath odataSelectPath = BuildSelectPath(autoSelectProperty, navigationSource);
                PathSelectItem  pathSelectItem  = new PathSelectItem(odataSelectPath);
                autoSelectItems.Add(pathSelectItem);
            }

            depth--;
            if (depth < 0)
            {
                return;
            }

            IList <ExpandModelPath> autoExpandNavigationProperties = model.GetAutoExpandPaths(baseEntityType, null, !isAllSelected, modelBoundQuerySettings);

            foreach (ExpandModelPath itemPath in autoExpandNavigationProperties)
            {
                string navigationPath = itemPath.NavigationPropertyPath;
                IEdmNavigationProperty navigationProperty = itemPath.Navigation;

                IEdmNavigationSource currentEdmNavigationSource;
                if (navigationPath != null)
                {
                    currentEdmNavigationSource = navigationSource.FindNavigationTarget(navigationProperty);
                }
                else
                {
                    currentEdmNavigationSource = navigationSource.FindNavigationTarget(navigationProperty, new EdmPathExpression(navigationPath));
                }

                if (currentEdmNavigationSource != null)
                {
                    ODataExpandPath expandPath = BuildExpandPath(itemPath, navigationSource, currentEdmNavigationSource);

                    SelectExpandClause           selectExpandClause = new SelectExpandClause(new List <SelectItem>(), true);
                    ExpandedNavigationSelectItem item = new ExpandedNavigationSelectItem(expandPath, currentEdmNavigationSource, selectExpandClause);
                    modelBoundQuerySettings = model.GetModelBoundQuerySettings(navigationProperty, navigationProperty.ToEntityType());
                    List <SelectItem> nestedSelectItems;
                    List <SelectItem> nestedExpandItems;

                    int maxExpandDepth = GetMaxExpandDepth(modelBoundQuerySettings, navigationProperty.Name);
                    if (maxExpandDepth != 0 && maxExpandDepth < depth)
                    {
                        depth = maxExpandDepth;
                    }

                    GetAutoSelectExpandItems(
                        currentEdmNavigationSource.EntityType(),
                        model,
                        item.NavigationSource,
                        true,
                        modelBoundQuerySettings,
                        depth,
                        out nestedSelectItems,
                        out nestedExpandItems);

                    selectExpandClause = new SelectExpandClause(nestedSelectItems.Concat(nestedExpandItems), nestedSelectItems.Count == 0);
                    item = new ExpandedNavigationSelectItem(expandPath, currentEdmNavigationSource, selectExpandClause);

                    autoExpandItems.Add(item);
                    if (!isAllSelected || autoSelectProperties.Any())
                    {
                        PathSelectItem pathSelectItem = new PathSelectItem(new ODataSelectPath(expandPath));
                        autoExpandItems.Add(pathSelectItem);
                    }
                }
            }
        }
        private static IEnumerable<SelectItem> GetAutoExpandedNavigationSelectItems(
            IEdmEntityType baseEntityType, 
            IEdmModel model,
            string alreadyExpandedNavigationSourceName,
            IEdmNavigationSource navigationSource,
            bool isAllSelected,
            bool searchDerivedTypeWhenAutoExpand)
        {
            var expandItems = new List<SelectItem>();
            var autoExpandNavigationProperties = EdmLibHelpers.GetAutoExpandNavigationProperties(baseEntityType, model,
                searchDerivedTypeWhenAutoExpand);
            foreach (var navigationProperty in autoExpandNavigationProperties)
            {
                if (!alreadyExpandedNavigationSourceName.Equals(navigationProperty.Name))
                {
                    IEdmEntityType entityType = navigationProperty.DeclaringEntityType();
                    IEdmNavigationSource currentEdmNavigationSource =
                        navigationSource.FindNavigationTarget(navigationProperty);

                    if (currentEdmNavigationSource != null)
                    {
                        List<ODataPathSegment> pathSegments = new List<ODataPathSegment>()
                        {
                            new NavigationPropertySegment(navigationProperty, currentEdmNavigationSource)
                        };

                        ODataExpandPath expandPath = new ODataExpandPath(pathSegments);
                        SelectExpandClause selectExpandClause = new SelectExpandClause(new List<SelectItem>(),
                            true);
                        ExpandedNavigationSelectItem item = new ExpandedNavigationSelectItem(expandPath,
                            currentEdmNavigationSource, selectExpandClause);
                        if (!currentEdmNavigationSource.EntityType().Equals(entityType))
                        {
                            IEnumerable<SelectItem> nestedSelectItems = GetAutoExpandedNavigationSelectItems(
                                currentEdmNavigationSource.EntityType(),
                                model,
                                alreadyExpandedNavigationSourceName,
                                item.NavigationSource,
                                true,
                                searchDerivedTypeWhenAutoExpand);
                            selectExpandClause = new SelectExpandClause(nestedSelectItems, true);
                            item = new ExpandedNavigationSelectItem(expandPath, currentEdmNavigationSource,
                                selectExpandClause);
                        }

                        expandItems.Add(item);
                        if (!isAllSelected)
                        {
                            PathSelectItem pathSelectItem = new PathSelectItem(
                                new ODataSelectPath(pathSegments));
                            expandItems.Add(pathSelectItem);
                        }
                    }
                }
            }
            return expandItems;
        }