Example #1
0
        protected virtual async Task <IQueryExecutionResult> ExecuteAsyncGrouping <T>(CancellationToken cancellationToken)
        {
            var result = new QueryExecutionResult();

            // preserve queryable.
            var queryableAfterFilters = CurrentQueryable;

            // async.
            result.TotalRecords = await this.AsyncQueryableService.LongCountAsync((IQueryable <T>) queryableAfterFilters, cancellationToken);

            CalculatePageCount(result);

            // intercept groups in advance to avoid doing it more than once :)
            var finalGroups = Criteria.Groups.Select(g => InterceptGroup <T>(g)).ToList();

            // get the aggregates.
            var aggregateResults = await FetchAggregatesAsync <T>(finalGroups, cancellationToken);

            // sorting.
            finalGroups.ForEach(fg => Criteria.Sorts.Insert(0, new Sort(fg.Path, fg.Ascending)));

            // apply sorting and paging.
            ApplySorting <T>();
            ApplyPaging <T>();

            // create group & select expression.
            CurrentQueryable = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb => finalGroups.ForEach((fg, index) => gb.Path(fg.Path, $"Key_{index}")));
            CurrentQueryable = CurrentQueryable.Select(sb =>
            {
                finalGroups.ForEach((fg, index) => sb.Key($"Key_{index}", $"Key_{index}"));
                sb.ToList("Records");
            });

            // loop through the grouped records.
//            var groupRecords = await AsyncQueryableService.ToListAsync(CurrentQueryable.Cast<DynamicClass>(), cancellationToken);

            // now join them into logical collections
//            result.Data = RecursiveRegroup<T>(groupRecords, aggregateResults, Criteria.Groups.First());
            result.Data       = CurrentQueryable;
            result.Aggregates = await CalculateTotalAggregateAsync <T>(queryableAfterFilters, cancellationToken);

            return(result);
        }