grouping is starting well :P

This commit is contained in:
David Lebee 2018-10-19 16:44:13 -05:00
parent 65db65171a
commit 8ca897b304
7 changed files with 108 additions and 15 deletions

View File

@ -47,6 +47,7 @@ namespace PoweredSoft.DynamicQuery.Cli
public int Id { get; set; } public int Id { get; set; }
public string FirstName { get; set; } public string FirstName { get; set; }
public string LastName { get; set; } public string LastName { get; set; }
public int Age { get; set; }
} }
public class OtherClass public class OtherClass
@ -67,11 +68,11 @@ namespace PoweredSoft.DynamicQuery.Cli
{ {
var list = new List<Person>() var list = new List<Person>()
{ {
new Person{ Id = 1, FirstName = "David", LastName = "Lebee"}, new Person{ Id = 1, FirstName = "David", LastName = "Lebee", Age = 29},
new Person{ Id = 2, FirstName = "Michaela", LastName = "Lebee"}, new Person{ Id = 2, FirstName = "Michaela", LastName = "Lebee", Age = 29},
new Person{ Id = 3, FirstName = "Zohra", LastName = "Lebee"}, new Person{ Id = 3, FirstName = "Zohra", LastName = "Lebee", Age = 20},
new Person{ Id = 4, FirstName = "Eric", LastName = "Vickar"}, new Person{ Id = 4, FirstName = "Eric", LastName = "Vickar", Age = 30},
new Person{ Id = 5, FirstName = "Susan", LastName = "Vickar"}, new Person{ Id = 5, FirstName = "Susan", LastName = "Vickar", Age = 30},
}; };
var queryable = list.AsQueryable(); var queryable = list.AsQueryable();
@ -79,6 +80,7 @@ namespace PoweredSoft.DynamicQuery.Cli
criteria.Page = 1; criteria.Page = 1;
criteria.PageSize = 10; criteria.PageSize = 10;
/*
criteria.Filters = new List<IFilter> criteria.Filters = new List<IFilter>
{ {
new SimpleFilter() {Path = nameof(Person.LastName), Value = "Lebee", Type = FilterType.Equal}, new SimpleFilter() {Path = nameof(Person.LastName), Value = "Lebee", Type = FilterType.Equal},
@ -92,8 +94,19 @@ namespace PoweredSoft.DynamicQuery.Cli
new SimpleFilter() {Path = nameof(Person.FirstName), Value = "Zohra", Type = FilterType.Equal}, new SimpleFilter() {Path = nameof(Person.FirstName), Value = "Zohra", Type = FilterType.Equal},
} }
} }
};*/
criteria.Groups = new List<IGroup>()
{
new Group { Path = "LastName" }
}; };
criteria.Aggregates = new List<IAggregate>()
{
new Aggregate { Path = "Age", Type = AggregateType.Count },
new Aggregate { Path = "Age", Type = AggregateType.Avg }
};;
var handler = new QueryHandler(); var handler = new QueryHandler();
handler.AddInterceptor(new PersonQueryInterceptor()); handler.AddInterceptor(new PersonQueryInterceptor());
var result = handler.Execute(queryable, criteria); var result = handler.Execute(queryable, criteria);

View File

@ -5,7 +5,6 @@
Count, Count,
Sum, Sum,
Avg, Avg,
Max, LongCount
Min
} }
} }

View File

@ -4,6 +4,6 @@ namespace PoweredSoft.DynamicQuery.Core
{ {
public interface ISortInterceptor : IQueryInterceptor public interface ISortInterceptor : IQueryInterceptor
{ {
IEnumerable<ISort> InterceptSort(ISort sort); IEnumerable<ISort> InterceptSort(IEnumerable<ISort> sort);
} }
} }

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
using PoweredSoft.DynamicQuery.Core;
namespace PoweredSoft.DynamicQuery
{
public class Aggregate : IAggregate
{
public string Path { get; set; }
public AggregateType Type { get; set; }
}
}

View File

@ -35,5 +35,19 @@ namespace PoweredSoft.DynamicQuery.Extensions
return null; return null;
} }
public static SelectTypes? SelectType(this AggregateType aggregateType)
{
if (aggregateType == AggregateType.Avg)
return SelectTypes.Average;
if (aggregateType == AggregateType.Count)
return SelectTypes.Count;
if (aggregateType == AggregateType.LongCount)
return SelectTypes.LongCount;
if (aggregateType == AggregateType.Sum)
return SelectTypes.Sum;
return null;
}
} }
} }

View File

@ -23,9 +23,35 @@ namespace PoweredSoft.DynamicQuery
protected virtual IQueryExecutionResult ExecuteGrouping<T>() protected virtual IQueryExecutionResult ExecuteGrouping<T>()
{ {
throw new NotImplementedException(); var result = new GroupedQueryExecutionResult();
result.TotalRecords = CurrentQueryable.LongCount();
Criteria.Groups.ForEach(group =>
{
var finalGroup = InterceptGroup<T>(group);
var groupCleanedPath = group.Path.Replace(".", "");
CurrentQueryable = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb =>
{
gb.Path(finalGroup.Path);
});
CurrentQueryable = CurrentQueryable.Select(sb =>
{
sb.ToList("Data");
sb.Key($"Group_{groupCleanedPath}", group.Path);
Criteria.Aggregates.ForEach(a =>
{
var selectType = ResolveSelectFrom(a.Type);
var pathCleaned = a.Path.Replace(".", "");
sb.Aggregate(a.Path, selectType, $"Agg_{a.Type}_{pathCleaned}");
});
});
});
return result;
} }
protected virtual IQueryExecutionResult ExecuteNoGrouping<T>() protected virtual IQueryExecutionResult ExecuteNoGrouping<T>()
{ {
var result = new QueryExecutionResult(); var result = new QueryExecutionResult();

View File

@ -38,6 +38,17 @@ namespace PoweredSoft.DynamicQuery
Interceptors.Add(interceptor); Interceptors.Add(interceptor);
} }
protected virtual IGroup InterceptGroup<T>(IGroup group)
{
var ret = Interceptors
.Where(t => t is IGroupingInterceptor)
.Cast<IGroupingInterceptor>()
.Aggregate(group, (prev, inter) => inter.InterceptGroup(prev));
return ret;
}
protected virtual void ApplyNoGroupingPaging<T>() protected virtual void ApplyNoGroupingPaging<T>()
{ {
if (!HasPaging) if (!HasPaging)
@ -66,12 +77,18 @@ namespace PoweredSoft.DynamicQuery
protected virtual List<ISort> InterceptSort<T>(ISort sort) protected virtual List<ISort> InterceptSort<T>(ISort sort)
{ {
var original = new List<ISort>()
{
sort
};
var ret = Interceptors var ret = Interceptors
.Where(t => t is ISortInterceptor) .Where(t => t is ISortInterceptor)
.Cast<ISortInterceptor>() .Cast<ISortInterceptor>()
.SelectMany(interceptor => interceptor.InterceptSort(sort)); .Aggregate(original as IEnumerable<ISort>, (prev, inter) => inter.InterceptSort(prev))
.Distinct();
return ret.Distinct().ToList(); return ret.ToList();
} }
protected virtual void ApplyNoSortInterceptor<T>() protected virtual void ApplyNoSortInterceptor<T>()
@ -85,17 +102,28 @@ namespace PoweredSoft.DynamicQuery
.Aggregate((IQueryable<T>)CurrentQueryable, (prev, interceptor) => interceptor.InterceptNoSort(prev)); .Aggregate((IQueryable<T>)CurrentQueryable, (prev, interceptor) => interceptor.InterceptNoSort(prev));
} }
protected virtual ConditionOperators? ResolveFromOrDefault(FilterType filterType) => filterType.ConditionOperator();
protected virtual ConditionOperators ResolveFrom(FilterType filterType) protected virtual SelectTypes? ResolveSelectFromOrDefault(AggregateType aggregateType) => aggregateType.SelectType();
protected virtual ConditionOperators? ResolveConditionOperatorFromOrDefault(FilterType filterType) => filterType.ConditionOperator();
protected virtual ConditionOperators ResolveConditionOperatorFrom(FilterType filterType)
{ {
var ret = ResolveFromOrDefault(filterType); var ret = ResolveConditionOperatorFromOrDefault(filterType);
if (ret == null) if (ret == null)
throw new NotSupportedException($"{filterType} is not supported"); throw new NotSupportedException($"{filterType} is not supported");
return ret.Value; return ret.Value;
} }
protected virtual SelectTypes ResolveSelectFrom(AggregateType aggregateType)
{
var ret = ResolveSelectFromOrDefault(aggregateType);
if (ret == null)
throw new NotSupportedException($"{aggregateType} is not supported");
return ret.Value;
}
protected virtual void ApplyFilters<T>() protected virtual void ApplyFilters<T>()
{ {
if (true != Criteria.Filters?.Any()) if (true != Criteria.Filters?.Any())
@ -125,7 +153,7 @@ namespace PoweredSoft.DynamicQuery
protected virtual void ApplySimpleFilter<T>(WhereBuilder whereBuilder, ISimpleFilter filter) protected virtual void ApplySimpleFilter<T>(WhereBuilder whereBuilder, ISimpleFilter filter)
{ {
var resolvedConditionOperator = ResolveFrom(filter.Type); var resolvedConditionOperator = ResolveConditionOperatorFrom(filter.Type);
whereBuilder.Compare(filter.Path, resolvedConditionOperator, filter.Value, and: filter.And == true); whereBuilder.Compare(filter.Path, resolvedConditionOperator, filter.Value, and: filter.And == true);
} }