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