private FilteredPaginationQuery Clone(FilteredPaginationQuery org) { var ret = JsonConvert.DeserializeObject <FilteredPaginationQuery>(JsonConvert.SerializeObject(org)); ret.SetAliasesAndValues(_queryParams); return(ret); }
/// <summary> /// Builds a filtered paged result query from a filtered queryable, where server side paging is enforced. /// </summary> /// <typeparam name="TIn">The type of the t in.</typeparam> /// <typeparam name="TOut">The type of the t out.</typeparam> /// <param name="qry">The qry.</param> /// <param name="request">The request.</param> /// <param name="maxItemsPerResult">max items that should override the queries top.</param> /// <param name="projection">Select projection</param> /// <param name="serializeSettings">Map serialize settings</param> /// <returns>Task<List<TOut>>.</returns> public static IQueryable FilteredPagedResultsQuery <TIn, TOut>(this IQueryable <TIn> qry, FilteredPaginationQuery request, int maxItemsPerResult, Func <TIn, TOut> projection = null, JsonSerializerSettings serializeSettings = null ) where TOut : new() { var result = qry.BuildPagedQueryable(request, maxItemsPerResult) .BuildFilteredQueryable(request) .BuildOutputQueryable(projection, serializeSettings); Console.WriteLine(result.Expression.ToString()); return(result); }
private PaginationMetadata BuildResponseFromQuery(int resultCount, string baseUrl) { var requestQuery = new FilteredPaginationQuery(); requestQuery.SetAliasesAndValues(_queryParams); var maxPageSize = (requestQuery.Top.IsNullOrZero() ? requestQuery.Skip.IsNullOrZero() ? resultCount : requestQuery.Skip : requestQuery.Top) ?? resultCount; // If resultCount is 0 or empty then we are just going to display the structure. // If resultCount is less than the max, and no query params have been passed then no need to have anything either. if (resultCount == 0 || resultCount < maxPageSize && !_queryParams.Any()) { return new PaginationMetadata { ResultCount = resultCount } } ; var previousRc = requestQuery.RunningCount - resultCount; SetRunningCount(requestQuery, resultCount); FilteredPaginationQuery previousQuery = null; FilteredPaginationQuery nextQuery = null; if (requestQuery.Skip.IsNullOrZero() && requestQuery.Top.IsNullOrZero()) { // No inputs, create new ones, no need to new up previousQuery. // Set the top (take) to be the max and the skip to be what was just returned, resultCount. var top = GetTop(requestQuery, maxPageSize); nextQuery = Clone(requestQuery); nextQuery.Skip = requestQuery.RunningCount; nextQuery.Top = top; nextQuery.RunningCount = requestQuery.RunningCount; } else if (!requestQuery.Top.IsNullOrZero() && requestQuery.Skip.IsNullOrZero()) { // Only top specified, se we use it. var top = GetTop(requestQuery, maxPageSize); nextQuery = Clone(requestQuery); nextQuery.Skip = requestQuery.RunningCount; nextQuery.Top = top; nextQuery.RunningCount = requestQuery.RunningCount; } else if (requestQuery.Top.HasValue) { var top = GetTop(requestQuery, maxPageSize); var pre = GetPreviousSkip(requestQuery, maxPageSize); var next = GetNextSkip(requestQuery, maxPageSize); var nextRc = requestQuery.RunningCount; previousQuery = Clone(requestQuery); previousQuery.Top = top; previousQuery.Skip = pre; previousQuery.RunningCount = previousRc <= 0 ? null : previousRc; // Do we need next? if (resultCount >= maxPageSize) { nextQuery = Clone(requestQuery); nextQuery.Skip = next; nextQuery.Top = top; nextQuery.RunningCount = nextRc; } } if (nextQuery is not null) { nextQuery.Undefined = requestQuery.Undefined; } if (previousQuery is not null) { previousQuery.Undefined = previousQuery.Undefined; } var ret = new PaginationMetadata { ResultCount = resultCount, Next = nextQuery is null ? null : string.Format(baseUrl, nextQuery), Previous = previousQuery is null ? null : string.Format(baseUrl, previousQuery) }; // if previous is empty and we do not have more than top, then next should be null as well. if (ret.Previous is not null) { return(ret); } if (nextQuery is not null && resultCount < nextQuery.Top) { ret.Next = null; } return(ret); }