finding matching aggregate works.

This commit is contained in:
David Lebee 2018-10-21 14:46:33 -05:00
parent 4bb96b2058
commit 7a8ee0895c
2 changed files with 85 additions and 45 deletions

View File

@ -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>()
{

View File

@ -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;
}
}
}