Ejemplo n.º 1
0
        object IODataSerializer.Serialize <TElement>(IODataProjectResult <TElement> projectResult)
        {
            Throw.IfNull(projectResult, "projectResult");

            // TODO VNext this doesn't seem like the best place for this logic. Consider changing
            // the pipeline APIs so that this logic can happen earlier
            IEnumerable projectedQuery;
            int?        inlineCount;

            PaginationHelper.Paginate(projectResult, out projectedQuery, out inlineCount);

            var result = this.Serialize(projectedQuery, projectResult.ProjectMapping, inlineCount);

            return(result);
        }
        object IODataServiceQueryPipeline.Serialize <TElement>(IODataProjectResult <TElement> projectResult)
        {
            Throw.IfNull(projectResult, "projectResult");
            // MA: TryGetValue throws on nulls, so we need this to be a separate check
            Throw <NotSupportedException> .If(projectResult.ODataQuery.Format == null, "No format argument was provided");

            Throw <NotSupportedException> .If(
                !this._serializersByFormat.TryGetValue(projectResult.ODataQuery.Format, out var serializer),
                "No serializer is available for the given format"
                );

            var result = serializer.Serialize(projectResult);

            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Optimizes pagination and counting by avoiding projection reads when <see cref="ODataQueryExpression.Top"/> is 0 and
        /// avoiding counts when on the last page of items (where count can be inferred)
        /// </summary>
        public static void Paginate <TElement>(IODataProjectResult <TElement> projectResult, out IEnumerable projectEnumerable, out int?count)
        {
            // if we're doing top(0), we can skip projection and just count. This is the case when a client calls .Count() on an OData queryable
            if (projectResult.ODataQuery.Top == 0)
            {
                projectEnumerable = Enumerable.Empty <object>();
                count             = projectResult.ODataQuery.InlineCount == ODataInlineCountOption.AllPages
                    ? projectResult.InlineCountQuery.Count()
                    : default(int?);
                return;
            }

            // if we're counting...
            if (projectResult.ODataQuery.InlineCount == ODataInlineCountOption.AllPages)
            {
                // Enumerable.Cast to ensure in-memory cast
                var projectArray = Enumerable.Cast <object>(projectResult.ProjectedResultQuery).ToArray();
                projectEnumerable = projectArray;

                // ... and we're on the last page, we can skip the count

                if (!projectResult.ODataQuery.Top.HasValue ||
                    projectArray.Length < projectResult.ODataQuery.Top.Value)
                {
                    count = projectResult.ODataQuery.Skip + projectArray.Length;
                }
                else
                {
                    count = projectResult.InlineCountQuery.Count();
                }
                return;
            }

            // otherwise, don't count
            projectEnumerable = projectResult.ProjectedResultQuery;
            count             = null;
        }