예제 #1
0
        public PaginatedResult <TSelect> LimitedSearch <TGroup, TSelect>(
            IDataFilter <TDataModel> filter,
            IDataLimiter <TDataModel> limiter,
            IDataProjection <TDataModel, TGroup, TSelect> projection)
        {
            Checker.NotNullArgument(filter, nameof(filter));
            Checker.NotNullArgument(limiter, nameof(limiter));
            Checker.NotNullArgument(projection, nameof(projection));
            Checker.NotNullObject(projection.Group,
                                  $"{nameof(projection)}.{nameof(projection.Group)}");
            Checker.NotNullObject(projection.Select,
                                  $"{nameof(projection)}.{nameof(projection.Select)}");

            var query = QuerySearch(_query, filter, projection);

            // A projeção já foi aplicada em QuerySearch(),
            // por isso não precisa ser repassada aqui
            var(offset, limit, total, result) = QueryPreLimitResult(query, limiter, null);

            return(new PaginatedResult <TSelect>(
                       result.GroupBy(projection.Group).Select(projection.Select).ToList(),
                       offset,
                       limit,
                       total
                       ));
        }
예제 #2
0
        public PaginatedResult <TDataModel> LimitedGet(IDataLimiter <TDataModel> limiter,
                                                       IDataIncludes includes)
        {
            Checker.NotNullArgument(limiter, nameof(limiter));

            var(offset, limit, total, result) = QueryPreLimitResult(_query, limiter, includes);

            return(new PaginatedResult <TDataModel>(
                       result.ToList(),
                       offset,
                       limit,
                       total
                       ));
        }
예제 #3
0
        public PaginatedResult <TSelect> LimitedGet <TSelect>(IDataLimiter <TDataModel> limiter,
                                                              IDataProjection <TDataModel, TSelect> projection)
        {
            Checker.NotNullArgument(limiter, nameof(limiter));
            Checker.NotNullArgument(projection, nameof(projection));
            Checker.NotNullObject(projection.Select,
                                  $"{nameof(projection)}.{nameof(projection.Select)}");

            var(offset, limit, total, result) = QueryPreLimitResult(_query, limiter, projection);

            return(new PaginatedResult <TSelect>(
                       result.Select(projection.Select).ToList(),
                       offset,
                       limit,
                       total
                       ));
        }
예제 #4
0
        public PaginatedResult <TDataModel> LimitedSearch(IDataFilter <TDataModel> filter,
                                                          IDataLimiter <TDataModel> limiter, IDataIncludes includes)
        {
            Checker.NotNullArgument(filter, nameof(filter));
            Checker.NotNullArgument(limiter, nameof(limiter));

            var query = QuerySearch(_query, filter, includes);

            // A projeção já foi aplicada em QuerySearch(),
            // por isso não precisa ser repassada aqui
            var(offset, limit, total, result) = QueryPreLimitResult(query, limiter, null);

            return(new PaginatedResult <TDataModel>(
                       result.ToList(),
                       offset,
                       limit,
                       total
                       ));
        }
예제 #5
0
        /// <summary>
        /// Query for operations that must return an <see cref="PaginatedResult{TDataModel}" />
        /// </summary>
        /// <param name="limiter">Data limiter</param>
        /// <param name="origin">Original data query</param>
        /// <param name="includes">Data includes</param>
        /// <returns>Tuple of (offset, limit, total, result)</returns>
        protected (uint, uint, int, IQueryable <TDataModel>) QueryPreLimitResult(
            IQueryable <TDataModel> origin,
            IDataLimiter <TDataModel> limiter,
            IDataIncludes includes)
        {
            Checker.NotNullArgument(limiter, nameof(limiter));
            Checker.NotNullArgument(origin, nameof(origin));

            // Ensures offset range
            if (limiter.OffsetLimit.HasValue &&
                (limiter.OffsetLimit.Value == 0 || limiter.OffsetLimit.Value > int.MaxValue))
            {
                throw new ArgumentOutOfRangeException($"limiter.{limiter.OffsetLimit}");
            }

            var result = TryApplyIncludes(origin, includes);

            IOrderedQueryable <TDataModel> orderBy = null;

            foreach (var sorter in limiter.GetSorters())
            {
                if (orderBy == null)
                {
                    orderBy = sorter.Descending
                        ? result.OrderByDescending(sorter.Sorter)
                        : result.OrderBy(sorter.Sorter);
                }
                else
                {
                    orderBy = sorter.Descending
                        ? orderBy.ThenByDescending(sorter.Sorter)
                        : orderBy.ThenBy(sorter.Sorter);
                }
            }

            result = orderBy ?? result;

            uint offset;
            uint limit;

            var total = result.Count();

            if (limiter.OffsetBegin.HasValue)
            {
                offset = limiter.OffsetBegin.Value;
                result = result.Skip(Convert.ToInt32(offset));
            }
            else
            {
                offset = 0;
            }

            if (limiter.OffsetLimit.HasValue)
            {
                limit  = limiter.OffsetLimit.Value;
                result = result.Take(Convert.ToInt32(limit));
            }
            else
            {
                limit = Convert.ToUInt32(total);
            }

            return(offset, limit, total, result);
        }