/// <summary>
        /// Create an expand item, using a navigationProperty, its entity set, and any expand options.
        /// </summary>
        /// <param name="pathToNavigationProperty">the path to the navigation property for this expand item, including any type segments</param>
        /// <param name="navigationSource">the navigation source for this expand level.</param>
        /// <param name="filterOption">A filter clause for this expand (can be null)</param>
        /// <param name="orderByOption">An Orderby clause for this expand (can be null)</param>
        /// <param name="topOption">A top clause for this expand (can be null)</param>
        /// <param name="skipOption">A skip clause for this expand (can be null)</param>
        /// <param name="countOption">An query count clause for this expand (can be null)</param>
        /// <param name="searchOption">A search clause for this expand (can be null)</param>
        /// <param name="computeOption">A compute clause for this expand (can be null)</param>
        /// <param name="applyOption">A apply clause for this expand (can be null)</param>
        /// <exception cref="System.ArgumentNullException">Throws if input pathToNavigationProperty is null.</exception>
        public ExpandedReferenceSelectItem(
            ODataExpandPath pathToNavigationProperty,
            IEdmNavigationSource navigationSource,
            FilterClause filterOption,
            OrderByClause orderByOption,
            long?topOption,
            long?skipOption,
            bool?countOption,
            SearchClause searchOption,
            ComputeClause computeOption,
            ApplyClause applyOption)
        {
            ExceptionUtils.CheckArgumentNotNull(pathToNavigationProperty, "pathToNavigationProperty");

            this.PathToNavigationProperty = pathToNavigationProperty;
            this.NavigationSource         = navigationSource;
            this.FilterOption             = filterOption;
            this.OrderByOption            = orderByOption;
            this.TopOption     = topOption;
            this.SkipOption    = skipOption;
            this.CountOption   = countOption;
            this.SearchOption  = searchOption;
            this.ComputeOption = computeOption;
            this.ApplyOption   = applyOption;
        }
 /// <summary>
 /// Create an expand item, using a navigationProperty, its entity set, and any expand options.
 /// </summary>
 /// <param name="pathToNavigationProperty">the path to the navigation property for this expand item, including any type segments</param>
 /// <param name="navigationSource">the navigation source for this expand level.</param>
 /// <param name="filterOption">A filter clause for this expand (can be null)</param>
 /// <param name="orderByOption">An Orderby clause for this expand (can be null)</param>
 /// <param name="topOption">A top clause for this expand (can be null)</param>
 /// <param name="skipOption">A skip clause for this expand (can be null)</param>
 /// <param name="countOption">An query count clause for this expand (can be null)</param>
 /// <param name="searchOption">A search clause for this expand (can be null)</param>
 /// <exception cref="System.ArgumentNullException">Throws if input pathToNavigationProperty is null.</exception>
 public ExpandedReferenceSelectItem(
     ODataExpandPath pathToNavigationProperty,
     IEdmNavigationSource navigationSource,
     FilterClause filterOption,
     OrderByClause orderByOption,
     long?topOption,
     long?skipOption,
     bool?countOption,
     SearchClause searchOption)
     : this(pathToNavigationProperty, navigationSource, filterOption, orderByOption, topOption, skipOption, countOption, searchOption, null)
 {
 }
        /// <summary>
        /// Create an expand item, using a navigationProperty, its entity set, and any expand options.
        /// </summary>
        /// <param name="pathToNavigationProperty">the path to the navigation property for this expand item, including any type segments</param>
        /// <param name="navigationSource">the navigation source for this expand level.</param>
        /// <param name="selectAndExpand">This level select and any sub expands for this expand item.</param>
        /// <param name="filterOption">A filter clause for this expand (can be null)</param>
        /// <param name="orderByOption">An Orderby clause for this expand (can be null)</param>
        /// <param name="topOption">A top clause for this expand (can be null)</param>
        /// <param name="skipOption">A skip clause for this expand (can be null)</param>
        /// <param name="countOption">An query count clause for this expand (can be null)</param>
        /// <param name="searchOption">An levels clause for this expand (can be null)</param>
        /// <param name="levelsOption">An levels clause for this expand (can be null)</param>
        /// <exception cref="System.ArgumentNullException">Throws if input pathToNavigationProperty is null.</exception>
        public ExpandedNavigationSelectItem(
            ODataExpandPath pathToNavigationProperty,
            IEdmNavigationSource navigationSource,
            SelectExpandClause selectAndExpand,
            FilterClause filterOption,
            OrderByClause orderByOption,
            long?topOption,
            long?skipOption,
            bool?countOption,
            SearchClause searchOption,
            LevelsClause levelsOption)
            : base(pathToNavigationProperty, navigationSource, filterOption, orderByOption, topOption, skipOption, countOption, searchOption)
        {
            ExceptionUtils.CheckArgumentNotNull(pathToNavigationProperty, "pathToNavigationProperty");

            this.SelectAndExpand = selectAndExpand;
            this.LevelsOption    = levelsOption;
        }
Beispiel #4
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");

            PathSegmentToken currentToken = tokenIn.PathToNavigationProp;

            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;
            IEdmStructuralProperty currentComplexProp = edmProperty as IEdmStructuralProperty;

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

            if (currentComplexProp != null)
            {
                currentNavProp = ParseComplexTypesBeforeNavigation(currentComplexProp, ref firstNonTypeToken, pathSoFar);
            }

            // ensure that we're always dealing with proper V4 syntax
            if (firstNonTypeToken.NextToken != null && firstNonTypeToken.NextToken.NextToken != null)
            {
                throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath);
            }

            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);
                }
            }

            // Add the segments in select and expand to parsed segments
            List <ODataPathSegment> parsedPath = new List <ODataPathSegment>(this.parsedSegments);

            parsedPath.AddRange(pathSoFar);

            IEdmNavigationSource targetNavigationSource = null;

            if (this.NavigationSource != null)
            {
                IEdmPathExpression bindingPath;
                targetNavigationSource = this.NavigationSource.FindNavigationTarget(currentNavProp, BindingPathHelper.MatchBindingPath, parsedPath, out bindingPath);
            }

            NavigationPropertySegment navSegment = new NavigationPropertySegment(currentNavProp, targetNavigationSource);

            pathSoFar.Add(navSegment);
            parsedPath.Add(navSegment); // Add the navigation property segment to parsed segments for future usage.
            ODataExpandPath pathToNavProp = new ODataExpandPath(pathSoFar);

            // $apply
            ApplyClause applyOption = BindApply(tokenIn.ApplyOptions, targetNavigationSource);

            // $compute
            ComputeClause computeOption = BindCompute(tokenIn.ComputeOption, targetNavigationSource);

            var  generatedProperties = GetGeneratedProperties(computeOption, applyOption);
            bool collapsed           = applyOption?.Transformations.Any(t => t.Kind == TransformationNodeKind.Aggregate || t.Kind == TransformationNodeKind.GroupBy) ?? false;

            // $filter
            FilterClause filterOption = BindFilter(tokenIn.FilterOption, targetNavigationSource, null, generatedProperties, collapsed);

            // $orderby
            OrderByClause orderbyOption = BindOrderby(tokenIn.OrderByOptions, targetNavigationSource, null, generatedProperties, collapsed);

            // $search
            SearchClause searchOption = BindSearch(tokenIn.SearchOption, targetNavigationSource, null);

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

            // $select & $expand
            SelectExpandClause subSelectExpand = BindSelectExpand(tokenIn.ExpandOption, tokenIn.SelectOption, parsedPath, targetNavigationSource, null, generatedProperties, collapsed);

            // $levels
            LevelsClause levelsOption = ParseLevels(tokenIn.LevelsOption, currentLevelEntityType, currentNavProp);

            return(new ExpandedNavigationSelectItem(pathToNavProp,
                                                    targetNavigationSource, subSelectExpand, filterOption, orderbyOption, tokenIn.TopOption, tokenIn.SkipOption, tokenIn.CountQueryOption, searchOption, levelsOption, computeOption, applyOption));
        }
 /// <summary>
 /// Create an Expand item using a nav prop, its entity set and a SelectExpandClause
 /// </summary>
 /// <param name="pathToNavigationProperty">the path to the navigation property for this expand item, including any type segments</param>
 /// <param name="navigationSource">the navigation source for this ExpandItem</param>
 /// <param name="selectExpandOption">This level select and any sub expands for this expand item.</param>
 /// <exception cref="System.ArgumentNullException">Throws if input pathToNavigationProperty is null.</exception>
 public ExpandedNavigationSelectItem(ODataExpandPath pathToNavigationProperty, IEdmNavigationSource navigationSource, SelectExpandClause selectExpandOption)
     : this(pathToNavigationProperty, navigationSource, selectExpandOption, null, null, null, null, null, null, null)
 {
 }
 /// <summary>
 /// Create an Expand item using a nav prop, its entity set
 /// </summary>
 /// <param name="pathToNavigationProperty">the path to the navigation property for this expand item, including any type segments</param>
 /// <param name="navigationSource">the navigation source for this ExpandItem</param>
 /// <exception cref="System.ArgumentNullException">Throws if input pathToNavigationProperty is null.</exception>
 public ExpandedReferenceSelectItem(ODataExpandPath pathToNavigationProperty, IEdmNavigationSource navigationSource)
     : this(pathToNavigationProperty, navigationSource, null, null, null, null, null, null)
 {
 }
 /// <summary>
 /// Translate an ODataExpandPath into an ODataSelectPath
 /// Depending on the constructor of ODataSelectPath to validate that we aren't adding any
 /// segments that are illegal for a select.
 /// </summary>
 /// <param name="path">the ODataExpandPath to translate</param>
 /// <returns>A new ODataSelect path with the same segments as the expand path.</returns>
 public static ODataSelectPath ToSelectPath(this ODataExpandPath path)
 {
     return(new ODataSelectPath(path));
 }
Beispiel #8
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");

            PathSegmentToken currentToken = tokenIn.PathToNavigationProp;

            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;
            IEdmStructuralProperty currentComplexProp = edmProperty as IEdmStructuralProperty;

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

            if (currentComplexProp != null)
            {
                currentNavProp = ParseComplexTypesBeforeNavigation(currentComplexProp, ref firstNonTypeToken, pathSoFar);
            }

            // ensure that we're always dealing with proper V4 syntax
            if (firstNonTypeToken.NextToken != null && firstNonTypeToken.NextToken.NextToken != null)
            {
                throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath);
            }

            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);
                }
            }

            // Add the segments in select and expand to parsed segments
            this.parsedSegments.AddRange(pathSoFar);

            IEdmNavigationSource targetNavigationSource = null;

            if (this.NavigationSource != null)
            {
                IEdmPathExpression bindingPath;
                targetNavigationSource = this.NavigationSource.FindNavigationTarget(currentNavProp, BindingPathHelper.MatchBindingPath, this.parsedSegments, out bindingPath);
            }

            NavigationPropertySegment navSegment = new NavigationPropertySegment(currentNavProp, targetNavigationSource);

            pathSoFar.Add(navSegment);
            this.parsedSegments.Add(navSegment);   // Add the navigation property segment to parsed segments for future usage.
            ODataExpandPath pathToNavProp = new ODataExpandPath(pathSoFar);

            // 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(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 #9
0
 public ExpandedCountSelectItem(ODataExpandPath pathToNavigationProperty, IEdmNavigationSource navigationSource) : base(pathToNavigationProperty, navigationSource)
 {
 }
Beispiel #10
0
 /// <summary>
 /// Create an Expand item using a nav prop, its entity set and a SelectExpandClause
 /// </summary>
 /// <param name="pathToNavigationProperty">the path to the navigation property for this expand item, including any type segments</param>
 /// <param name="navigationSource">the navigation source for this ExpandItem</param>
 /// <param name="filterOption">A filter clause for this expand (can be null)</param>
 /// <param name="searchOption">A search clause for this expand (can be null)</param>
 /// <exception cref="System.ArgumentNullException">Throws if input pathToNavigationProperty is null.</exception>
 public ExpandedCountSelectItem(ODataExpandPath pathToNavigationProperty, IEdmNavigationSource navigationSource, FilterClause filterOption, SearchClause searchOption)
     : base(pathToNavigationProperty, navigationSource, filterOption, null, null, null, null, searchOption)
 {
     ExceptionUtils.CheckArgumentNotNull(pathToNavigationProperty, "pathToNavigationProperty");
 }