finding matching aggregate works.
This commit is contained in:
		
							parent
							
								
									4bb96b2058
								
							
						
					
					
						commit
						7a8ee0895c
					
				@ -32,52 +32,16 @@ namespace PoweredSoft.DynamicQuery
 | 
			
		||||
            var finalGroups = Criteria.Groups.Select(g => InterceptGroup<T>(g)).ToList();
 | 
			
		||||
 | 
			
		||||
            // get the aggregates.
 | 
			
		||||
            List<List<DynamicClass>> aggregateResults = null;
 | 
			
		||||
            if (Criteria.Aggregates.Any())
 | 
			
		||||
            {
 | 
			
		||||
                var previousGroups = new List<IGroup>();
 | 
			
		||||
                aggregateResults = finalGroups.Select(fg =>
 | 
			
		||||
                {
 | 
			
		||||
                    var groupExpression = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb =>
 | 
			
		||||
                    {
 | 
			
		||||
                        var groupKeyIndex = -1;
 | 
			
		||||
                        previousGroups.ForEach(pg =>gb.Path(pg.Path, $"Key_{++groupKeyIndex}"));
 | 
			
		||||
                        gb.Path(fg.Path, $"Key_{++groupKeyIndex}");
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    var selectExpression = groupExpression.Select(sb =>
 | 
			
		||||
                    {
 | 
			
		||||
                        var groupKeyIndex = -1;
 | 
			
		||||
                        previousGroups.ForEach(pg => sb.Key($"Key_{++groupKeyIndex}"));
 | 
			
		||||
                        sb.Key($"Key_{++groupKeyIndex}", $"Key_{groupKeyIndex}");
 | 
			
		||||
                        Criteria.Aggregates.ForEach(a =>
 | 
			
		||||
                        {
 | 
			
		||||
                            var selectType = ResolveSelectFrom(a.Type);
 | 
			
		||||
                            var pathCleaned = a.Path?.Replace(".", "");
 | 
			
		||||
                            sb.Aggregate(a.Path, selectType, $"Agg_{a.Type}_{pathCleaned}");
 | 
			
		||||
                        });
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    var aggregateResult = selectExpression.ToDynamicClassList();
 | 
			
		||||
                    previousGroups.Add(fg);
 | 
			
		||||
                    return aggregateResult;
 | 
			
		||||
                }).ToList();
 | 
			
		||||
            }
 | 
			
		||||
            var aggregateResults = Criteria.Aggregates.Any() ? FetchAggregates(finalGroups) : null;
 | 
			
		||||
 | 
			
		||||
            // sorting.
 | 
			
		||||
            finalGroups.ForEach(fg =>
 | 
			
		||||
            {
 | 
			
		||||
                Criteria.Sorts.Insert(0, new Sort()
 | 
			
		||||
                {
 | 
			
		||||
                    Path = fg.Path,
 | 
			
		||||
                    Ascending = fg.Ascending
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
            finalGroups.ForEach(fg => Criteria.Sorts.Insert(0, new Sort(fg.Path, fg.Ascending)));
 | 
			
		||||
 | 
			
		||||
            // apply sorting and paging.
 | 
			
		||||
            ApplySorting<T>();
 | 
			
		||||
            ApplyPaging<T>();
 | 
			
		||||
 | 
			
		||||
            // now get the data grouped.
 | 
			
		||||
            // create group & select expression.
 | 
			
		||||
            CurrentQueryable = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb => finalGroups.ForEach((fg, index) => gb.Path(fg.Path, $"Key_{index}")));
 | 
			
		||||
            CurrentQueryable = CurrentQueryable.Select(sb =>
 | 
			
		||||
            {
 | 
			
		||||
@ -85,12 +49,13 @@ namespace PoweredSoft.DynamicQuery
 | 
			
		||||
                sb.ToList("Records");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // loop through the grouped records.
 | 
			
		||||
            var groupRecords = CurrentQueryable.ToDynamicClassList();
 | 
			
		||||
            result.Data = groupRecords.Select((groupRecord, groupRecordIndex) =>
 | 
			
		||||
            {
 | 
			
		||||
                var groupRecordResult = new GroupQueryResult();
 | 
			
		||||
                GroupQueryResult previous = null;
 | 
			
		||||
 | 
			
		||||
                List<GroupQueryResult> previousGroupResults = new List<GroupQueryResult>();
 | 
			
		||||
                List<IGroup> previousGroups = new List<IGroup>();
 | 
			
		||||
                Criteria.Groups.ForEach((g, gi) =>
 | 
			
		||||
                {
 | 
			
		||||
                    bool isFirst = gi == 0;
 | 
			
		||||
@ -99,16 +64,25 @@ namespace PoweredSoft.DynamicQuery
 | 
			
		||||
                    cgrr.GroupPath = g.Path;
 | 
			
		||||
                    cgrr.GroupValue = groupRecord.GetDynamicPropertyValue($"Key_{gi}");
 | 
			
		||||
 | 
			
		||||
                 
 | 
			
		||||
 | 
			
		||||
                    if (!isLast)
 | 
			
		||||
                        cgrr.Data = new List<object>();
 | 
			
		||||
                    else
 | 
			
		||||
                        cgrr.Data = groupRecord.GetDynamicPropertyValue<List<T>>("Records").Cast<object>().ToList();
 | 
			
		||||
 | 
			
		||||
                    if (previous != null)
 | 
			
		||||
                        previous.Data.Add(cgrr);
 | 
			
		||||
                    if (previousGroupResults.Any())
 | 
			
		||||
                        previousGroupResults.Last().Data.Add(cgrr);
 | 
			
		||||
 | 
			
		||||
                    previous = cgrr;
 | 
			
		||||
                    previousGroupResults.Add(cgrr);
 | 
			
		||||
                    previousGroups.Add(g);
 | 
			
		||||
 | 
			
		||||
                    // find aggregates for this group.
 | 
			
		||||
                    if (Criteria.Aggregates.Any())
 | 
			
		||||
                    {
 | 
			
		||||
                        var matchingAggregate = FindMatchingAggregateResult(aggregateResults, previousGroups, previousGroupResults);
 | 
			
		||||
                        cgrr.Aggregates = new List<IAggregateResult>();
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                return (object)groupRecordResult;
 | 
			
		||||
@ -117,7 +91,57 @@ namespace PoweredSoft.DynamicQuery
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private DynamicClass FindMatchingAggregateResult(List<List<DynamicClass>> aggregateResults, List<IGroup> groups, List<GroupQueryResult> groupResults)
 | 
			
		||||
        {
 | 
			
		||||
            var groupIndex = groupResults.Count - 1;
 | 
			
		||||
            var aggregateLevel = aggregateResults[groupIndex];
 | 
			
		||||
 | 
			
		||||
            var ret = aggregateLevel.FirstOrDefault(al =>
 | 
			
		||||
            {
 | 
			
		||||
                for (var i = 0; i < groups.Count; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!al.GetDynamicPropertyValue($"Key_{i}").Equals(groupResults[i].GroupValue))
 | 
			
		||||
                        return false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return true;
 | 
			
		||||
            });
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private List<List<DynamicClass>> FetchAggregates(List<IGroup> finalGroups)
 | 
			
		||||
        {
 | 
			
		||||
            List<List<DynamicClass>> aggregateResults;
 | 
			
		||||
            var previousGroups = new List<IGroup>();
 | 
			
		||||
            aggregateResults = finalGroups.Select(fg =>
 | 
			
		||||
            {
 | 
			
		||||
                var groupExpression = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb =>
 | 
			
		||||
                {
 | 
			
		||||
                    var groupKeyIndex = -1;
 | 
			
		||||
                    previousGroups.ForEach(pg => gb.Path(pg.Path, $"Key_{++groupKeyIndex}"));
 | 
			
		||||
                    gb.Path(fg.Path, $"Key_{++groupKeyIndex}");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                var selectExpression = groupExpression.Select(sb =>
 | 
			
		||||
                {
 | 
			
		||||
                    var groupKeyIndex = -1;
 | 
			
		||||
                    previousGroups.ForEach(pg => sb.Key($"Key_{++groupKeyIndex}", $"Key_{groupKeyIndex}"));
 | 
			
		||||
                    sb.Key($"Key_{++groupKeyIndex}", $"Key_{groupKeyIndex}");
 | 
			
		||||
                    Criteria.Aggregates.ForEach(a =>
 | 
			
		||||
                    {
 | 
			
		||||
                        var selectType = ResolveSelectFrom(a.Type);
 | 
			
		||||
                        var pathCleaned = a.Path?.Replace(".", "");
 | 
			
		||||
                        sb.Aggregate(a.Path, selectType, $"Agg_{a.Type}_{pathCleaned}");
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                var aggregateResult = selectExpression.ToDynamicClassList();
 | 
			
		||||
                previousGroups.Add(fg);
 | 
			
		||||
                return aggregateResult;
 | 
			
		||||
            }).ToList();
 | 
			
		||||
            return aggregateResults;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual IQueryExecutionResult ExecuteNoGrouping<T>()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
@ -9,5 +9,21 @@ namespace PoweredSoft.DynamicQuery
 | 
			
		||||
    {
 | 
			
		||||
        public string Path { get; set; }
 | 
			
		||||
        public bool? Ascending { get; set; }
 | 
			
		||||
 | 
			
		||||
        public Sort()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Sort(string path)
 | 
			
		||||
        {
 | 
			
		||||
            Path = path;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Sort(string path, bool? ascending)
 | 
			
		||||
        {
 | 
			
		||||
            Path = path;
 | 
			
		||||
            Ascending = ascending;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user