Beispiel #1
0
        private static ODataPath CreatePath(ODataPath parentPath, ODataExpandPath pathToNavigationProperty)
        {
            var segments = new List <ODataPathSegment>(parentPath);

            segments.AddRange(pathToNavigationProperty);
            return(new ODataPath(segments));
        }
        public void GetFirstNonTypeCastSegment_WorksForExpandPathWithPropertySegment()
        {
            // Arrange
            EdmEntityType          entityType = new EdmEntityType("NS", "Customer");
            IEdmStructuralProperty property   = entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.String);
            var navProperty = entityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "Nav",
                Target             = entityType,
                TargetMultiplicity = EdmMultiplicity.One
            });
            EdmEntityContainer        container  = new EdmEntityContainer("NS", "Container");
            EdmEntitySet              set        = new EdmEntitySet(container, "set", entityType);
            NavigationPropertySegment navSegment = new NavigationPropertySegment(navProperty, set);
            TypeSegment      typeSegment         = new TypeSegment(entityType, null);
            ODataPathSegment propertySegment     = new PropertySegment(property);
            ODataExpandPath  expandPath          = new ODataExpandPath(typeSegment, propertySegment, navSegment);

            // Act
            IList <ODataPathSegment> remainingSegments;
            ODataPathSegment         firstNonTypeSegment = expandPath.GetFirstNonTypeCastSegment(out remainingSegments);

            // Assert
            Assert.NotNull(firstNonTypeSegment);
            Assert.Same(propertySegment, firstNonTypeSegment);

            Assert.NotNull(remainingSegments);
            Assert.Same(navSegment, Assert.Single(remainingSegments));
        }
        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);
        }
        public void GetFirstNonTypeCastSegment_ExpandPath_ThrowsArgumentNull()
        {
            // Arrange & Act
            ODataExpandPath          expandPath = null;
            IList <ODataPathSegment> remainingSegments;

            // Assert
            ExceptionAssert.ThrowsArgumentNull(() => expandPath.GetFirstNonTypeCastSegment(out remainingSegments), "expandPath");
        }
Beispiel #5
0
        private SelectExpandClause BuildSelectExpandClause(IEdmEntitySet entitySet, GraphQLSelectionSet selectionSet)
        {
            var selectItems = new List <SelectItem>();

            foreach (ASTNode astNode in selectionSet.Selections)
            {
                if (astNode is GraphQLFieldSelection fieldSelection)
                {
                    IEdmProperty edmProperty = FindEdmProperty(entitySet.EntityType(), fieldSelection.Name.Value);
                    if (fieldSelection.SelectionSet == null)
                    {
                        var structuralProperty = (IEdmStructuralProperty)edmProperty;
                        selectItems.Add(new PathSelectItem(new ODataSelectPath(new PropertySegment(structuralProperty))));
                    }
                    else
                    {
                        var           navigationProperty = (IEdmNavigationProperty)edmProperty;
                        IEdmEntitySet parentEntitySet;
                        if (navigationProperty.ContainsTarget)
                        {
                            ModelBuilder.ManyToManyJoinDescription joinDescription = _edmModel.GetManyToManyJoinDescription(navigationProperty);
                            parentEntitySet = OeEdmClrHelper.GetEntitySet(_edmModel, joinDescription.TargetNavigationProperty);
                        }
                        else
                        {
                            parentEntitySet = OeEdmClrHelper.GetEntitySet(_edmModel, navigationProperty);
                        }

                        var expandPath = new ODataExpandPath(new NavigationPropertySegment(navigationProperty, parentEntitySet));

                        FilterClause filterOption = null;
                        if (fieldSelection.Arguments.Any())
                        {
                            filterOption = BuildFilterClause(parentEntitySet, fieldSelection);
                        }

                        SelectExpandClause childSelectExpand = BuildSelectExpandClause(parentEntitySet, fieldSelection.SelectionSet);
                        var expandedSelectItem = new ExpandedNavigationSelectItem(expandPath, parentEntitySet, childSelectExpand, filterOption, null, null, null, null, null, null);
                        selectItems.Add(expandedSelectItem);
                    }
                }
                else
                {
                    throw new NotSupportedException("selection " + astNode.GetType().Name + " not supported");
                }
            }

            return(new SelectExpandClause(selectItems, false));
        }
Beispiel #6
0
        /// <summary>
        /// Verify the $expand path and gets the first non type cast segment in this expand path.
        /// For example: $expand=NS.SubType1/abc/NS.SubType2/nav
        /// => firstPropertySegment: "abc"
        /// => remainingSegments:  NS.SubType2/nav
        /// => leadingTypeSegment: NS.SubType1
        /// </summary>
        /// <param name="expandPath">The input $expand path.</param>
        /// <param name="remainingSegments">The remaining segments after the first non type segment.</param>
        /// <returns>First non-type cast segment.</returns>
        public static ODataPathSegment GetFirstNonTypeCastSegment(this ODataExpandPath expandPath,
                                                                  out IList <ODataPathSegment> remainingSegments)
        {
            if (expandPath == null)
            {
                throw new ArgumentNullException(nameof(expandPath));
            }

            // In fact, ODataExpandPath constructor verifies the supporting segments, we add the verification here for double check.
            return(GetFirstNonTypeCastSegment(expandPath,
                                              //The middle segment should be "TypeSegment" or "PropertySegment".
                                              m => m is PropertySegment || m is TypeSegment,
                                              // The last segment could be "NavigationPropertySegment"
                                              s => s is NavigationPropertySegment,
                                              out remainingSegments));
        }
Beispiel #7
0
        private SelectExpandClause BuildSelectExpandClause(IEdmEntitySet entitySet, GraphQLSelectionSet selectionSet)
        {
            var selectItems = new List <SelectItem>();

            foreach (ASTNode astNode in selectionSet.Selections)
            {
                if (astNode is GraphQLFieldSelection fieldSelection)
                {
                    IEdmProperty edmProperty = FindEdmProperty(entitySet.EntityType(), fieldSelection.Name.Value);
                    if (fieldSelection.SelectionSet == null)
                    {
                        var structuralProperty = (IEdmStructuralProperty)edmProperty;
                        selectItems.Add(new PathSelectItem(new ODataSelectPath(new PropertySegment(structuralProperty))));
                    }
                    else
                    {
                        IEdmType edmType = edmProperty.Type.Definition;
                        if (edmType is IEdmCollectionType collectionType)
                        {
                            edmType = collectionType.ElementType.Definition;
                        }

                        IEdmEntitySet      parentEntitySet   = OeEdmClrHelper.GetEntitySet(_edmModel, edmType);
                        SelectExpandClause childSelectExpand = BuildSelectExpandClause(parentEntitySet, fieldSelection.SelectionSet);

                        var           navigationProperty = (IEdmNavigationProperty)edmProperty;
                        IEdmEntitySet navigationSource   = OeEdmClrHelper.GetEntitySet(_edmModel, navigationProperty.Type.Definition);
                        var           expandPath         = new ODataExpandPath(new NavigationPropertySegment(navigationProperty, navigationSource));

                        FilterClause filterOption = null;
                        if (fieldSelection.Arguments.Any())
                        {
                            filterOption = BuildFilterClause(parentEntitySet, fieldSelection);
                        }

                        var expandedSelectItem = new ExpandedNavigationSelectItem(expandPath, navigationSource, childSelectExpand, filterOption, null, null, null, null, null, null);
                        selectItems.Add(expandedSelectItem);
                    }
                }
                else
                {
                    throw new NotSupportedException("selection " + astNode.GetType().Name + " not supported");
                }
            }

            return(new SelectExpandClause(selectItems, false));
        }
Beispiel #8
0
        /// <summary>
        /// Add sub $expand item for this include property.
        /// </summary>
        /// <param name="remainingSegments">The remaining segments star from this include property.</param>
        /// <param name="oldRefItem">The old $expand item.</param>
        public void AddSubExpandItem(IList <ODataPathSegment> remainingSegments, ExpandedReferenceSelectItem oldRefItem)
        {
            // remainingSegments should never be null, because at least a navigation property segment in it.
            Contract.Assert(remainingSegments != null);

            if (_subSelectItems == null)
            {
                _subSelectItems = new List <SelectItem>();
            }

            ODataExpandPath newPath = new ODataExpandPath(remainingSegments);
            ExpandedNavigationSelectItem expandedNav = oldRefItem as ExpandedNavigationSelectItem;

            if (expandedNav != null)
            {
                _subSelectItems.Add(new ExpandedNavigationSelectItem(newPath,
                                                                     expandedNav.NavigationSource,
                                                                     expandedNav.SelectAndExpand,
                                                                     expandedNav.FilterOption,
                                                                     expandedNav.OrderByOption,
                                                                     expandedNav.TopOption,
                                                                     expandedNav.SkipOption,
                                                                     expandedNav.CountOption,
                                                                     expandedNav.SearchOption,
                                                                     expandedNav.LevelsOption,
                                                                     expandedNav.ComputeOption,
                                                                     expandedNav.ApplyOption));
            }
            else
            {
                _subSelectItems.Add(new ExpandedReferenceSelectItem(newPath,
                                                                    oldRefItem.NavigationSource,
                                                                    oldRefItem.FilterOption,
                                                                    oldRefItem.OrderByOption,
                                                                    oldRefItem.TopOption,
                                                                    oldRefItem.SkipOption,
                                                                    oldRefItem.CountOption,
                                                                    oldRefItem.SearchOption,
                                                                    oldRefItem.ComputeOption,
                                                                    oldRefItem.ApplyOption));
            }
        }
        public ExpandDepthAndCountValidatorTests()
        {
            this.emptyTree = new SelectExpandClause(new SelectItem[0], true);
            var pathToMyDog = new ODataExpandPath(new NavigationPropertySegment(HardCodedTestModel.GetPersonMyDogNavProp(), HardCodedTestModel.GetDogsSet()));

            this.treeWithDepth1 = new SelectExpandClause(new[] { new ExpandedNavigationSelectItem(pathToMyDog, HardCodedTestModel.GetDogsSet(), this.emptyTree) }, true);
            var pathToPerson = new ODataExpandPath(new NavigationPropertySegment(HardCodedTestModel.GetDogMyPeopleNavProp(), HardCodedTestModel.GetPeopleSet()));

            this.treeWithDepth2 = new SelectExpandClause(new[] { new ExpandedNavigationSelectItem(pathToPerson, HardCodedTestModel.GetPeopleSet(), this.treeWithDepth1) }, true);
            var pathToLions = new ODataExpandPath(new NavigationPropertySegment(HardCodedTestModel.GetPersonMyLionsNavProp(), HardCodedTestModel.GetLionSet()));

            this.treeWithWidth2 = new SelectExpandClause(new[] { new ExpandedNavigationSelectItem(pathToMyDog, HardCodedTestModel.GetDogsSet(), this.emptyTree), new ExpandedNavigationSelectItem(pathToLions, HardCodedTestModel.GetLionSet(), this.emptyTree) }, true);
            this.treeWithDepthAndWidth2WithRepeatedParent = new SelectExpandClause(new[] { new ExpandedNavigationSelectItem(pathToPerson, HardCodedTestModel.GetPeopleSet(), this.treeWithWidth2) }, true);
            var pathToPaintings = new ODataExpandPath(new NavigationPropertySegment(HardCodedTestModel.GetPersonMyPaintingsNavProp(), HardCodedTestModel.GetPaintingsSet()));

            this.bigComplexTree = new SelectExpandClause(new[] {
                new ExpandedNavigationSelectItem(pathToMyDog, HardCodedTestModel.GetDogsSet(), this.treeWithDepthAndWidth2WithRepeatedParent),
                new ExpandedNavigationSelectItem(pathToLions, HardCodedTestModel.GetLionSet(), this.emptyTree),
                new ExpandedNavigationSelectItem(pathToPaintings, HardCodedTestModel.GetPaintingsSet(), this.emptyTree)
            }, true);
        }
Beispiel #10
0
        /// <summary>
        /// Generate an expand item (and a select item for the implicit nav prop if necessary) based on an ExpandTermToken
        /// </summary>
        /// <param name="tokenIn">the expandTerm token to visit</param>
        /// <returns>the expand item for this expand term token.</returns>
        private SelectItem GenerateExpandItem(ExpandTermToken tokenIn)
        {
            ExceptionUtils.CheckArgumentNotNull(tokenIn, "tokenIn");

            // ensure that we're always dealing with proper V4 syntax
            if (tokenIn.PathToNavProp.NextToken != null && !tokenIn.PathToNavProp.IsNamespaceOrContainerQualified())
            {
                if (tokenIn.PathToNavProp.NextToken.Identifier != UriQueryConstants.RefSegment || tokenIn.PathToNavProp.NextToken.NextToken != null)
                {
                    throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath);
                }
            }

            PathSegmentToken currentToken = tokenIn.PathToNavProp;

            IEdmStructuredType      currentLevelEntityType = this.EdmType;
            List <ODataPathSegment> pathSoFar         = new List <ODataPathSegment>();
            PathSegmentToken        firstNonTypeToken = currentToken;

            if (currentToken.IsNamespaceOrContainerQualified())
            {
                pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(currentToken, this.Model, this.Settings.SelectExpandLimit, this.configuration.Resolver, ref currentLevelEntityType, out firstNonTypeToken));
            }

            IEdmProperty edmProperty = this.configuration.Resolver.ResolveProperty(currentLevelEntityType, firstNonTypeToken.Identifier);

            if (edmProperty == null)
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclared(currentLevelEntityType.FullTypeName(), currentToken.Identifier));
            }

            IEdmNavigationProperty currentNavProp = edmProperty as IEdmNavigationProperty;

            if (currentNavProp == null)
            {
                throw new ODataException(ODataErrorStrings.ExpandItemBinder_PropertyIsNotANavigationProperty(currentToken.Identifier, currentLevelEntityType.FullTypeName()));
            }

            bool isRef = false;

            if (firstNonTypeToken.NextToken != null)
            {
                // lastly... make sure that, since we're on a NavProp, that the next token isn't null.
                if (firstNonTypeToken.NextToken.Identifier == UriQueryConstants.RefSegment)
                {
                    isRef = true;
                }
                else
                {
                    throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath);
                }
            }

            pathSoFar.Add(new NavigationPropertySegment(currentNavProp, /*entitySet*/ null));
            ODataExpandPath pathToNavProp = new ODataExpandPath(pathSoFar);

            IEdmNavigationSource targetNavigationSource = null;

            if (this.NavigationSource != null)
            {
                targetNavigationSource = this.NavigationSource.FindNavigationTarget(currentNavProp);
            }

            // call MetadataBinder to build the filter clause
            FilterClause filterOption = null;

            if (tokenIn.FilterOption != null)
            {
                MetadataBinder binder       = this.BuildNewMetadataBinder(targetNavigationSource);
                FilterBinder   filterBinder = new FilterBinder(binder.Bind, binder.BindingState);
                filterOption = filterBinder.BindFilter(tokenIn.FilterOption);
            }

            // call MetadataBinder again to build the orderby clause
            OrderByClause orderbyOption = null;

            if (tokenIn.OrderByOptions != null)
            {
                MetadataBinder binder        = this.BuildNewMetadataBinder(targetNavigationSource);
                OrderByBinder  orderByBinder = new OrderByBinder(binder.Bind);
                orderbyOption = orderByBinder.BindOrderBy(binder.BindingState, tokenIn.OrderByOptions);
            }

            SearchClause searchOption = null;

            if (tokenIn.SearchOption != null)
            {
                MetadataBinder binder       = this.BuildNewMetadataBinder(targetNavigationSource);
                SearchBinder   searchBinder = new SearchBinder(binder.Bind);
                searchOption = searchBinder.BindSearch(tokenIn.SearchOption);
            }

            if (isRef)
            {
                return(new ExpandedReferenceSelectItem(pathToNavProp, targetNavigationSource, filterOption, orderbyOption, tokenIn.TopOption, tokenIn.SkipOption, tokenIn.CountQueryOption, searchOption));
            }

            SelectExpandClause subSelectExpand;

            if (tokenIn.ExpandOption != null)
            {
                subSelectExpand = this.GenerateSubExpand(currentNavProp, tokenIn);
            }
            else
            {
                subSelectExpand = BuildDefaultSubExpand();
            }

            subSelectExpand = this.DecorateExpandWithSelect(subSelectExpand, currentNavProp, tokenIn.SelectOption);

            LevelsClause levelsOption = this.ParseLevels(tokenIn.LevelsOption, currentLevelEntityType, currentNavProp);

            return(new ExpandedNavigationSelectItem(pathToNavProp, targetNavigationSource, subSelectExpand, filterOption, orderbyOption, tokenIn.TopOption, tokenIn.SkipOption, tokenIn.CountQueryOption, searchOption, levelsOption));
        }
Beispiel #11
0
        /// <summary>
        /// Generate an expand item based on an ExpandTermToken
        /// </summary>
        /// <param name="tokenIn">the expandTerm token to visit</param>
        /// <returns>the expand item for this expand term token.</returns>
        private ExpandedNavigationSelectItem GenerateExpandItem(ExpandTermToken tokenIn)
        {
            ExceptionUtils.CheckArgumentNotNull(tokenIn, "tokenIn");

            // ensure that we're always dealing with a normalized tree
            if (tokenIn.PathToNavProp.NextToken != null && !tokenIn.PathToNavProp.IsNamespaceOrContainerQualified())
            {
                throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingANonNormalizedTree);
            }

            PathSegmentToken        currentToken           = tokenIn.PathToNavProp;
            IEdmEntityType          currentLevelEntityType = this.entityType;
            List <ODataPathSegment> pathSoFar         = new List <ODataPathSegment>();
            PathSegmentToken        firstNonTypeToken = currentToken;

            if (currentToken.IsNamespaceOrContainerQualified())
            {
                pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(currentToken, this.Model, this.Settings.SelectExpandLimit, ref currentLevelEntityType, out firstNonTypeToken));
            }

            IEdmProperty edmProperty = currentLevelEntityType.FindProperty(firstNonTypeToken.Identifier);

            if (edmProperty == null)
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclared(currentLevelEntityType.FullName(), currentToken.Identifier));
            }

            IEdmNavigationProperty currentNavProp = edmProperty as IEdmNavigationProperty;

            if (currentNavProp == null)
            {
                // the server allowed non-navigation, non-stream properties to be expanded, but then ignored them.
                if (this.Settings.UseWcfDataServicesServerBehavior && !edmProperty.Type.IsStream())
                {
                    return(null);
                }

                throw new ODataException(ODataErrorStrings.ExpandItemBinder_PropertyIsNotANavigationProperty(currentToken.Identifier, currentLevelEntityType.FullName()));
            }

            pathSoFar.Add(new NavigationPropertySegment(currentNavProp, /*entitySet*/ null));
            ODataExpandPath pathToNavProp = new ODataExpandPath(pathSoFar);

            SelectExpandClause subSelectExpand;

            if (tokenIn.ExpandOption != null)
            {
                subSelectExpand = this.GenerateSubExpand(currentNavProp, tokenIn);
            }
            else
            {
                subSelectExpand = BuildDefaultSubExpand();
            }

            subSelectExpand = this.DecorateExpandWithSelect(subSelectExpand, currentNavProp, tokenIn.SelectOption);

            IEdmEntitySet targetEntitySet = null;

            if (this.entitySet != null)
            {
                targetEntitySet = this.entitySet.FindNavigationTarget(currentNavProp);
            }

            // call MetadataBinder to build the filter clause
            FilterClause filterOption = null;

            if (tokenIn.FilterOption != null)
            {
                MetadataBinder binder       = this.BuildNewMetadataBinder(targetEntitySet);
                FilterBinder   filterBinder = new FilterBinder(binder.Bind, binder.BindingState);
                filterOption = filterBinder.BindFilter(tokenIn.FilterOption);
            }

            // call MetadataBinder again to build the orderby clause
            OrderByClause orderbyOption = null;

            if (tokenIn.OrderByOption != null)
            {
                MetadataBinder binder        = this.BuildNewMetadataBinder(targetEntitySet);
                OrderByBinder  orderByBinder = new OrderByBinder(binder.Bind);
                orderbyOption = orderByBinder.BindOrderBy(binder.BindingState, new OrderByToken[] { tokenIn.OrderByOption });
            }

            return(new ExpandedNavigationSelectItem(pathToNavProp, targetEntitySet, filterOption, orderbyOption, tokenIn.TopOption, tokenIn.SkipOption, tokenIn.InlineCountOption, subSelectExpand));
        }
Beispiel #12
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);
                    }
                }
            }
        }
Beispiel #13
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 void AppendExpression(ODataExpandPath path)
        {
            string text = path.ToContextUrlPathString();

            query.Append(text);
        }
Beispiel #15
0
        /// <summary>
        /// Build the $expand item, it maybe $expand=nav, $expand=complex/nav, $expand=nav/$ref, etc.
        /// </summary>
        /// <param name="expandReferenceItem">The expanded reference select item.</param>
        /// <param name="currentLevelPropertiesInclude">The current properties to include at current level.</param>
        /// <param name="structuralTypeInfo">The structural type properties.</param>
        private void BuildExpandItem(ExpandedReferenceSelectItem expandReferenceItem,
                                     IDictionary <IEdmStructuralProperty, SelectExpandIncludedProperty> currentLevelPropertiesInclude,
                                     EdmStructuralTypeInfo structuralTypeInfo)
        {
            Contract.Assert(expandReferenceItem != null && expandReferenceItem.PathToNavigationProperty != null);
            Contract.Assert(currentLevelPropertiesInclude != null);
            Contract.Assert(structuralTypeInfo != null);

            // Verify and process the $expand=abc/xyz/nav.
            ODataExpandPath          expandPath = expandReferenceItem.PathToNavigationProperty;
            IList <ODataPathSegment> remainingSegments;
            ODataPathSegment         segment = expandPath.GetFirstNonTypeCastSegment(out remainingSegments);

            PropertySegment firstPropertySegment = segment as PropertySegment;

            if (firstPropertySegment != null)
            {
                // for example: $expand=abc/xyz/nav, the remaining segment can't be null
                // because at least the last navigation property segment is there.
                Contract.Assert(remainingSegments != null);

                if (structuralTypeInfo.IsStructuralPropertyDefined(firstPropertySegment.Property))
                {
                    SelectExpandIncludedProperty newPropertySelectItem;
                    if (!currentLevelPropertiesInclude.TryGetValue(firstPropertySegment.Property, out newPropertySelectItem))
                    {
                        newPropertySelectItem = new SelectExpandIncludedProperty(firstPropertySegment);
                        currentLevelPropertiesInclude[firstPropertySegment.Property] = newPropertySelectItem;
                    }

                    newPropertySelectItem.AddSubExpandItem(remainingSegments, expandReferenceItem);
                }
            }
            else
            {
                // for example: $expand=nav, or $expand=NS.SubType/nav, the navigation property segment should be the last segment.
                // So, the remaining segments should be null.
                Contract.Assert(remainingSegments == null);

                NavigationPropertySegment firstNavigationSegment = segment as NavigationPropertySegment;
                Contract.Assert(firstNavigationSegment != null);

                if (structuralTypeInfo.IsNavigationPropertyDefined(firstNavigationSegment.NavigationProperty))
                {
                    // It's not allowed to have mulitple navigation expanded or referenced.
                    // for example: "$expand=nav($top=2),nav($skip=3)" is not allowed and will be merged (or throw exception) at ODL side.
                    ExpandedNavigationSelectItem expanded = expandReferenceItem as ExpandedNavigationSelectItem;
                    if (expanded != null)
                    {
                        if (ExpandedProperties == null)
                        {
                            ExpandedProperties = new Dictionary <IEdmNavigationProperty, ExpandedNavigationSelectItem>();
                        }

                        ExpandedProperties[firstNavigationSegment.NavigationProperty] = expanded;
                    }
                    else
                    {
                        // $expand=..../nav/$ref
                        if (ReferencedProperties == null)
                        {
                            ReferencedProperties = new Dictionary <IEdmNavigationProperty, ExpandedReferenceSelectItem>();
                        }

                        ReferencedProperties[firstNavigationSegment.NavigationProperty] = expandReferenceItem;
                    }
                }
            }
        }