コード例 #1
0
        /// <summary>
        /// Initialize the Node from <see cref="SelectExpandClause"/> for the given <see cref="IEdmStructuredType"/>.
        /// </summary>
        /// <param name="selectExpandClause">The input select and expand clause ($select and $expand).</param>
        /// <param name="structuredType">The related structural type to select and expand.</param>
        /// <param name="model">The Edm model.</param>
        /// <param name="expandedReference">Is expanded reference.</param>
        private void Initialize(SelectExpandClause selectExpandClause, IEdmStructuredType structuredType, IEdmModel model, bool expandedReference)
        {
            if (structuredType == null)
            {
                throw Error.ArgumentNull("structuredType");
            }

            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            IEdmEntityType entityType = structuredType as IEdmEntityType;

            if (expandedReference)
            {
                SelectAllDynamicProperties = false;
                if (entityType != null)
                {
                    // only need to include the key properties.
                    SelectedStructuralProperties = new HashSet <IEdmStructuralProperty>(entityType.Key());
                }
            }
            else
            {
                EdmStructuralTypeInfo structuralTypeInfo = new EdmStructuralTypeInfo(model, structuredType);

                if (selectExpandClause == null)
                {
                    SelectAllDynamicProperties = true;

                    // includes navigation properties
                    SelectedNavigationProperties = structuralTypeInfo.AllNavigationProperties;

                    // includes all bound actions
                    SelectedActions = structuralTypeInfo.AllActions;

                    // includes all bound functions
                    SelectedFunctions = structuralTypeInfo.AllFunctions;

                    // includes all structural properties
                    if (structuralTypeInfo.AllStructuralProperties != null)
                    {
                        foreach (var property in structuralTypeInfo.AllStructuralProperties)
                        {
                            AddStructuralProperty(property, null);
                        }
                    }
                }
                else
                {
                    BuildSelectExpand(selectExpandClause, structuralTypeInfo);
                }

                AdjustSelectNavigationProperties();
            }
        }
コード例 #2
0
        /// <summary>
        /// Build the $select item, it maybe $select=complex/abc, $select=abc, $select=nav, etc.
        /// </summary>
        /// <param name="pathSelectItem">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 BuildSelectItem(PathSelectItem pathSelectItem,
                                     IDictionary <IEdmStructuralProperty, SelectExpandIncludedProperty> currentLevelPropertiesInclude,
                                     EdmStructuralTypeInfo structuralTypeInfo)
        {
            Contract.Assert(pathSelectItem != null && pathSelectItem.SelectedPath != null);
            Contract.Assert(currentLevelPropertiesInclude != null);
            Contract.Assert(structuralTypeInfo != null);

            // Verify and process the $select=abc/xyz/....
            ODataSelectPath          selectPath = pathSelectItem.SelectedPath;
            IList <ODataPathSegment> remainingSegments;
            ODataPathSegment         segment = selectPath.GetFirstNonTypeCastSegment(out remainingSegments);

            PropertySegment firstPropertySegment = segment as PropertySegment;

            if (firstPropertySegment != null)
            {
                if (structuralTypeInfo.IsStructuralPropertyDefined(firstPropertySegment.Property))
                {
                    // $select=abc/xyz/...
                    SelectExpandIncludedProperty newPropertySelectItem;
                    if (!currentLevelPropertiesInclude.TryGetValue(firstPropertySegment.Property, out newPropertySelectItem))
                    {
                        newPropertySelectItem = new SelectExpandIncludedProperty(firstPropertySegment);
                        currentLevelPropertiesInclude[firstPropertySegment.Property] = newPropertySelectItem;
                    }

                    newPropertySelectItem.AddSubSelectItem(remainingSegments, pathSelectItem);
                }

                return;
            }

            // If the first segment is not a property segment,
            // that segment must be the last segment, so the remainging segments should be null.
            Contract.Assert(remainingSegments == null);

            NavigationPropertySegment navigationSegment = segment as NavigationPropertySegment;

            if (navigationSegment != null)
            {
                // for example: $select=NavigationProperty or $select=NS.VipCustomer/VipNav
                if (structuralTypeInfo.IsNavigationPropertyDefined(navigationSegment.NavigationProperty))
                {
                    if (SelectedNavigationProperties == null)
                    {
                        SelectedNavigationProperties = new HashSet <IEdmNavigationProperty>();
                    }

                    SelectedNavigationProperties.Add(navigationSegment.NavigationProperty);
                }

                return;
            }

            OperationSegment operationSegment = segment as OperationSegment;

            if (operationSegment != null)
            {
                // for example: $select=NS.Operation, or, $select=NS.VipCustomer/NS.Operation
                AddOperations(operationSegment, structuralTypeInfo.AllActions, structuralTypeInfo.AllFunctions);
                return;
            }

            DynamicPathSegment dynamicPathSegment = segment as DynamicPathSegment;

            if (dynamicPathSegment != null)
            {
                if (SelectedDynamicProperties == null)
                {
                    SelectedDynamicProperties = new HashSet <string>();
                }

                SelectedDynamicProperties.Add(dynamicPathSegment.Identifier);
                return;
            }

            // In fact, we should never be here, because it's verified above
            throw new ODataException(Error.Format(SRResources.SelectionTypeNotSupported, segment.GetType().Name));
        }
コード例 #3
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;
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Build $select and $expand clause
        /// </summary>
        /// <param name="selectExpandClause">The select expand clause</param>
        /// <param name="structuralTypeInfo">The structural type properties.</param>
        private void BuildSelectExpand(SelectExpandClause selectExpandClause, EdmStructuralTypeInfo structuralTypeInfo)
        {
            Contract.Assert(selectExpandClause != null);
            Contract.Assert(structuralTypeInfo != null);

            var currentLevelPropertiesInclude = new Dictionary <IEdmStructuralProperty, SelectExpandIncludedProperty>();

            // Explicitly set SelectAllDynamicProperties as false,
            // Below will re-set it as true if it meets the select all condition.
            SelectAllDynamicProperties = false;
            foreach (SelectItem selectItem in selectExpandClause.SelectedItems)
            {
                // $expand=...
                ExpandedReferenceSelectItem expandReferenceItem = selectItem as ExpandedReferenceSelectItem;
                if (expandReferenceItem != null)
                {
                    BuildExpandItem(expandReferenceItem, currentLevelPropertiesInclude, structuralTypeInfo);
                    continue;
                }

                PathSelectItem pathSelectItem = selectItem as PathSelectItem;
                if (pathSelectItem != null)
                {
                    // $select=abc/.../xyz
                    BuildSelectItem(pathSelectItem, currentLevelPropertiesInclude, structuralTypeInfo);
                    continue;
                }

                WildcardSelectItem wildCardSelectItem = selectItem as WildcardSelectItem;
                if (wildCardSelectItem != null)
                {
                    // $select=*
                    MergeAllStructuralProperties(structuralTypeInfo.AllStructuralProperties, currentLevelPropertiesInclude);
                    MergeSelectedNavigationProperties(structuralTypeInfo.AllNavigationProperties);
                    SelectAllDynamicProperties = true;
                    continue;
                }

                NamespaceQualifiedWildcardSelectItem wildCardActionSelection = selectItem as NamespaceQualifiedWildcardSelectItem;
                if (wildCardActionSelection != null)
                {
                    // $select=NS.*
                    AddNamespaceWildcardOperation(wildCardActionSelection, structuralTypeInfo.AllActions, structuralTypeInfo.AllFunctions);
                    continue;
                }

                throw new ODataException(Error.Format(SRResources.SelectionTypeNotSupported, selectItem.GetType().Name));
            }

            if (selectExpandClause.AllSelected)
            {
                MergeAllStructuralProperties(structuralTypeInfo.AllStructuralProperties, currentLevelPropertiesInclude);
                MergeSelectedNavigationProperties(structuralTypeInfo.AllNavigationProperties);
                MergeSelectedAction(structuralTypeInfo.AllActions);
                MergeSelectedFunction(structuralTypeInfo.AllFunctions);
                SelectAllDynamicProperties = true;
            }

            // to make sure the structural properties are in the same order defined in the type.
            if (structuralTypeInfo.AllStructuralProperties != null)
            {
                foreach (var structuralProperty in structuralTypeInfo.AllStructuralProperties)
                {
                    SelectExpandIncludedProperty includeProperty;
                    if (!currentLevelPropertiesInclude.TryGetValue(structuralProperty, out includeProperty))
                    {
                        continue;
                    }

                    PathSelectItem pathSelectItem = includeProperty == null ? null : includeProperty.ToPathSelectItem();
                    AddStructuralProperty(structuralProperty, pathSelectItem);
                }
            }
        }