コード例 #1
0
        /// <summary>
        /// Gets all of the entitySets that are involved for the given uri which includes expands
        /// </summary>
        /// <param name="uri">The uri to get the set for</param>
        /// <returns>The expected entity sets for the given uri</returns>
        internal static IEnumerable <EntitySet> GetIncludingExpandsSets(this ODataUri uri)
        {
            List <EntitySet> entitySets = new List <EntitySet>();

            EntitySet startingEntitySet = null;

            if (uri.TryGetExpectedEntitySet(out startingEntitySet))
            {
                // Review all expanded entity sets, get its version, if higher substitute its version
                foreach (IEnumerable <ODataUriSegment> segmentList in uri.ExpandSegments)
                {
                    EntitySet currentEntitySet = startingEntitySet;
                    foreach (ODataUriSegment segment in segmentList)
                    {
                        var navigationSegment = segment as NavigationSegment;
                        if (navigationSegment != null)
                        {
                            EntitySet relatedEntitySet = currentEntitySet.GetRelatedEntitySet(navigationSegment.NavigationProperty);

                            entitySets.Add(relatedEntitySet);
                            currentEntitySet = relatedEntitySet;
                        }
                    }
                }
            }

            return(entitySets);
        }
コード例 #2
0
        /// <summary>
        /// Gets all of the entitySets that are involved for the given uri which includes expands
        /// </summary>
        /// <param name="uri">The uri to get the set for</param>
        /// <returns>The expected entity sets for the given uri</returns>
        internal static IEnumerable <EntitySet> GetAllEntitySetsIncludingExpands(this ODataUri uri)
        {
            List <EntitySet> entitySets = new List <EntitySet>();

            EntitySet startingEntitySet = null;

            if (uri.TryGetExpectedEntitySet(out startingEntitySet))
            {
                entitySets.Add(startingEntitySet);
                entitySets.AddRange(GetIncludingExpandsSets(uri));
            }

            return(entitySets);
        }
コード例 #3
0
        internal static ODataUri ConstructODataUriWithoutActionInformation(IEnumerable<EntitySet> entitySets, ODataUri uri)
        {
            var segmentsToInclude = new List<ODataUriSegment>();
            ServiceOperationAnnotation serviceOperationAnnotation = null;
            string setName = null;
            foreach (var segment in uri.Segments)
            {
                var functionSegment = segment as FunctionSegment;
                if (functionSegment != null && functionSegment.Function.IsAction())
                {
                    serviceOperationAnnotation = functionSegment.Function.Annotations.OfType<ServiceOperationAnnotation>().Single();
                    var toggleBooleanAnnotation = functionSegment.Function.Annotations.OfType<ToggleBoolPropertyValueActionAnnotation>().SingleOrDefault();

                    if (toggleBooleanAnnotation != null)
                    {
                        setName = toggleBooleanAnnotation.SourceEntitySet;
                    }

                    break;
                }

                segmentsToInclude.Add(segment);
            }

            if (!serviceOperationAnnotation.BindingKind.IsBound())
            {
                ExceptionUtilities.CheckObjectNotNull(setName, "Cannot find the set name that the action starts from");
                var sourceEntitySet = entitySets.Single(es => es.Name == setName);
                segmentsToInclude.Add(new EntitySetSegment(sourceEntitySet));
            }

            var actionlessODataUri = new ODataUri(segmentsToInclude);
            actionlessODataUri.CustomQueryOptions = uri.CustomQueryOptions;
            actionlessODataUri.Filter = uri.Filter;
            actionlessODataUri.InlineCount = uri.InlineCount;
            actionlessODataUri.OrderBy = uri.OrderBy;
            actionlessODataUri.Skip = uri.Skip;
            actionlessODataUri.SkipToken = uri.SkipToken;
            actionlessODataUri.Top = uri.Top;
            EntitySet expectedEntitySet = null;

            ExceptionUtilities.Assert(actionlessODataUri.TryGetExpectedEntitySet(out expectedEntitySet), "Expected entity set not found");

            // expand all navigations for actionlessODataUri so that we do not need to send additional request when calculating expected action result
            foreach (NavigationProperty navigation in expectedEntitySet.EntityType.NavigationProperties)
            {
                actionlessODataUri.ExpandSegments.Add(new List<ODataUriSegment>() { new NavigationSegment(navigation) });
            }

            return actionlessODataUri;
        }
コード例 #4
0
        internal static bool ResponseMightIncludeNextLink(ODataUri uri)
        {
            var payloadsWithNextLinks = new[] { ODataPayloadElementType.EntitySetInstance, ODataPayloadElementType.LinkCollection };
            var expectedPayloadType = uri.GetExpectedPayloadType();
            if (!payloadsWithNextLinks.Contains(expectedPayloadType))
            {
                return false;
            }

            EntitySet expectedSet;
            ExceptionUtilities.Assert(uri.TryGetExpectedEntitySet(out expectedSet), "Could not get expected entity set");

            var pageSize = expectedSet.GetEffectivePageSize();
            if (!pageSize.HasValue)
            {
                return false;
            }

            // if the value of $top is less than 1 page size, no next link will be included
            return !uri.Top.HasValue || uri.Top.Value > pageSize.Value;
        }
コード例 #5
0
        /// <summary>
        /// Processes the given uri and produces an expected value according to the conventions of an OData server implementation
        /// </summary>
        /// <param name="uri">The uri to process</param>
        /// <param name="applySelectAndExpand">A value indicating whether or not $select and $expand should be applied to the query values</param>
        /// <param name="applyPaging">A value indicating whether server-driven paging should be applied to the query values</param>
        /// <returns>The value resulting from processing the uri</returns>
        public QueryValue Evaluate(ODataUri uri, bool applySelectAndExpand, bool applyPaging)
        {
            this.applyPagingInExpands = applyPaging;
            ExceptionUtilities.CheckArgumentNotNull(uri, "uri");
            ExceptionUtilities.CheckCollectionNotEmpty(uri.Segments, "uri.Segments");
            ExceptionUtilities.CheckAllRequiredDependencies(this);

            this.currentUri = uri;
            this.shouldLastSegmentBeSingleton = false;

            applyPaging &= uri.TryGetExpectedEntitySet(out this.expectedEntitySet);

            if (applyPaging)
            {
                // compute the expected page size for this request based on the existence of a universal page size or set-specific page size
                this.expectedPageSize = this.expectedEntitySet.GetEffectivePageSize();
            }
            else
            {
                this.expectedPageSize = null;
            }

            var query = this.BuildQueryFromSegments();
            ExceptionUtilities.CheckObjectNotNull(query, "Could not build query from uri '{0}'", uri);

            // we explicitly do not process expand or select here because they do not affect the number of rows returned or their ordering
            query = this.ProcessFilter(query);
            ExceptionUtilities.CheckObjectNotNull(query, "Could not build query from uri '{0}'", uri);

            if (uri.IsEntitySet())
            {
                // TODO: skip-token processing should happen before ordering
                query = this.ProcessOrderBy(query);
                ExceptionUtilities.CheckObjectNotNull(query, "Could not build query from uri '{0}'", uri);

                query = this.ProcessSkipAndTop(query);
                ExceptionUtilities.CheckObjectNotNull(query, "Could not build query from uri '{0}'", uri);
            }

            // handle $count requests
            if (uri.IsCount())
            {
                query = query.LongCount();
            }

            // need to resolve types since we constructed new QueryExpression tree
            var resolvedQuery = this.QueryResolver.Resolve(query);

            var value = this.Evaluator.Evaluate(resolvedQuery);
            ExceptionUtilities.CheckObjectNotNull(value, "Could not evaluate query '{0}'", query);
            ExceptionUtilities.Assert(value.EvaluationError == null, "Query evaluation produced an error: {0}", value.EvaluationError);

            // post-process the result to defer properties that were not expanded
            if (applySelectAndExpand)
            {
                value = this.ApplySelectAndExpand(uri, value);
            }

            // fixup for key expressions that should return singletons
            if (this.shouldLastSegmentBeSingleton)
            {
                value = EnsureLastSegmentIsSingletonOrNull(value);
            }

            this.currentUri = null;
            this.expectedEntitySet = null;
            this.expectedPageSize = null;

            return value;
        }