diff --git a/PoweredSoft.DynamicQuery.Cli/Program.cs b/PoweredSoft.DynamicQuery.Cli/Program.cs index da7f35f..b2a5a7c 100644 --- a/PoweredSoft.DynamicQuery.Cli/Program.cs +++ b/PoweredSoft.DynamicQuery.Cli/Program.cs @@ -8,6 +8,7 @@ using Newtonsoft.Json.Converters; namespace PoweredSoft.DynamicQuery.Cli { public class PersonQueryInterceptor : IQueryInterceptor + , IAggregateInterceptor //, IBeforeQueryAlteredInterceptor //, IFilterInterceptor { @@ -40,6 +41,13 @@ namespace PoweredSoft.DynamicQuery.Cli return filter; } + + public IAggregate InterceptAggregate(IAggregate aggregate) + { + if (aggregate.Path == nameof(Person.AgeStr)) + return new Aggregate {Type = aggregate.Type, Path = nameof(Person.Age)}; + return aggregate; + } } public class Person @@ -49,6 +57,7 @@ namespace PoweredSoft.DynamicQuery.Cli public string LastName { get; set; } public int Age { get; set; } public string Sexe { get; set; } + public string AgeStr => $"{Age} years old"; } public class OtherClass @@ -69,7 +78,7 @@ namespace PoweredSoft.DynamicQuery.Cli { var list = new List() { - new Person{ Id = 1, FirstName = "David", LastName = "Lebee", Sexe = "Male", Age = 29}, + new Person{ Id = 1, FirstName = "David", LastName = "Lebee", Sexe = "Male", Age = 29 }, new Person{ Id = 2, FirstName = "Michaela", LastName = "Lebee", Sexe = "Female", Age = 29}, new Person{ Id = 3, FirstName = "Zohra", LastName = "Lebee", Sexe = "Female", Age = 20}, new Person{ Id = 4, FirstName = "Eric", LastName = "Vickar", Sexe = "Male", Age = 30}, @@ -90,7 +99,7 @@ namespace PoweredSoft.DynamicQuery.Cli criteria.Aggregates = new List() { new Aggregate { Type = AggregateType.Count }, - new Aggregate { Path = "Age", Type = AggregateType.Avg } + new Aggregate { Path = "AgeStr", Type = AggregateType.Avg } };; var handler = new QueryHandler(); diff --git a/PoweredSoft.DynamicQuery.Core/IAggregateInterceptor.cs b/PoweredSoft.DynamicQuery.Core/IAggregateInterceptor.cs new file mode 100644 index 0000000..a5aac21 --- /dev/null +++ b/PoweredSoft.DynamicQuery.Core/IAggregateInterceptor.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace PoweredSoft.DynamicQuery.Core +{ + public interface IAggregateInterceptor : IQueryInterceptor + { + IAggregate InterceptAggregate(IAggregate aggregate); + } +} diff --git a/PoweredSoft.DynamicQuery/QueryHandler.cs b/PoweredSoft.DynamicQuery/QueryHandler.cs index 7e42010..4a26c34 100644 --- a/PoweredSoft.DynamicQuery/QueryHandler.cs +++ b/PoweredSoft.DynamicQuery/QueryHandler.cs @@ -36,7 +36,7 @@ namespace PoweredSoft.DynamicQuery var finalGroups = Criteria.Groups.Select(g => InterceptGroup(g)).ToList(); // get the aggregates. - var aggregateResults = Criteria.Aggregates.Any() ? FetchAggregates(finalGroups) : null; + var aggregateResults = FetchAggregates(finalGroups); // sorting. finalGroups.ForEach(fg => Criteria.Sorts.Insert(0, new Sort(fg.Path, fg.Ascending))); @@ -101,11 +101,11 @@ namespace PoweredSoft.DynamicQuery return (object)groupRecordResult; }).ToList(); - result.Aggregates = CalculateTotalAggregate(queryableAfterFilters); + result.Aggregates = CalculateTotalAggregate(queryableAfterFilters); return result; } - protected virtual List CalculateTotalAggregate(IQueryable queryableAfterFilters) + protected virtual List CalculateTotalAggregate(IQueryable queryableAfterFilters) { if (!Criteria.Aggregates.Any()) return null; @@ -115,8 +115,9 @@ namespace PoweredSoft.DynamicQuery { Criteria.Aggregates.ForEach((a, index) => { - var selectType = ResolveSelectFrom(a.Type); - sb.Aggregate(a.Path, selectType, $"Agg_{index}"); + var fa = InterceptAggregate(a); + var selectType = ResolveSelectFrom(fa.Type); + sb.Aggregate(fa.Path, selectType, $"Agg_{index}"); }); }); @@ -153,8 +154,11 @@ namespace PoweredSoft.DynamicQuery } - private List> FetchAggregates(List finalGroups) + private List> FetchAggregates(List finalGroups) { + if (!Criteria.Aggregates.Any()) + return null; + List> aggregateResults; var previousGroups = new List(); aggregateResults = finalGroups.Select(fg => @@ -173,8 +177,9 @@ namespace PoweredSoft.DynamicQuery sb.Key($"Key_{++groupKeyIndex}", $"Key_{groupKeyIndex}"); Criteria.Aggregates.ForEach((a, ai) => { - var selectType = ResolveSelectFrom(a.Type); - sb.Aggregate(a.Path, selectType, $"Agg_{ai}"); + var fa = InterceptAggregate(a); + var selectType = ResolveSelectFrom(fa.Type); + sb.Aggregate(fa.Path, selectType, $"Agg_{ai}"); }); }); @@ -202,7 +207,7 @@ namespace PoweredSoft.DynamicQuery // the data. result.Data = CurrentQueryable.ToObjectList(); - result.Aggregates = CalculateTotalAggregate(afterFilterQueryable); + result.Aggregates = CalculateTotalAggregate(afterFilterQueryable); return result; } diff --git a/PoweredSoft.DynamicQuery/QueryHandlerBase.cs b/PoweredSoft.DynamicQuery/QueryHandlerBase.cs index 50d0b50..842292c 100644 --- a/PoweredSoft.DynamicQuery/QueryHandlerBase.cs +++ b/PoweredSoft.DynamicQuery/QueryHandlerBase.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Linq; using System.Net; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using PoweredSoft.DynamicLinq.Fluent; @@ -86,6 +87,14 @@ namespace PoweredSoft.DynamicQuery result.NumberOfPages = result.TotalRecords / Criteria.PageSize + (result.TotalRecords % Criteria.PageSize != 0 ? 1 : 0); } + protected virtual IAggregate InterceptAggregate(IAggregate aggregate) + { + var ret = Interceptors + .Where(t => t is IAggregateInterceptor) + .Cast() + .Aggregate(aggregate, (prev, inter) => inter.InterceptAggregate(prev)); + return ret; + } protected virtual List InterceptSort(ISort sort) {