Advancing well.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using PoweredSoft.DynamicLinq;
|
||||
using PoweredSoft.DynamicQuery.Core;
|
||||
|
||||
namespace PoweredSoft.DynamicQuery.Extensions
|
||||
{
|
||||
public static class FilterTypeExtensions
|
||||
{
|
||||
public static ConditionOperators? ConditionOperator(this FilterType filterType)
|
||||
{
|
||||
if (filterType == FilterType.Equal)
|
||||
return ConditionOperators.Equal;
|
||||
if (filterType == FilterType.NotEqual)
|
||||
return ConditionOperators.NotEqual;
|
||||
if (filterType == FilterType.GreaterThan)
|
||||
return ConditionOperators.GreaterThan;
|
||||
if (filterType == FilterType.GreaterThanOrEqual)
|
||||
return ConditionOperators.GreaterThanOrEqual;
|
||||
if (filterType == FilterType.LessThan)
|
||||
return ConditionOperators.LessThan;
|
||||
if (filterType == FilterType.LessThanOrEqual)
|
||||
return ConditionOperators.LessThanOrEqual;
|
||||
if (filterType == FilterType.StartsWith)
|
||||
return ConditionOperators.StartsWith;
|
||||
if (filterType == FilterType.EndsWith)
|
||||
return ConditionOperators.EndsWith;
|
||||
if (filterType == FilterType.Contains)
|
||||
return ConditionOperators.Contains;
|
||||
if (filterType == FilterType.In)
|
||||
return ConditionOperators.In;
|
||||
if (filterType == FilterType.NotIn)
|
||||
return ConditionOperators.NotIn;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using PoweredSoft.DynamicQuery.Core;
|
||||
|
||||
namespace PoweredSoft.DynamicQuery
|
||||
{
|
||||
public abstract class Filter : IFilter
|
||||
{
|
||||
public bool? And { get; set; }
|
||||
public FilterType Type { get; set; }
|
||||
}
|
||||
|
||||
public class SimpleFilter : ISimpleFilter
|
||||
{
|
||||
public bool? And { get; set; }
|
||||
public FilterType Type { get; set; }
|
||||
public string Path { get; set; }
|
||||
public object Value { get; set; }
|
||||
}
|
||||
|
||||
public class CompositeFilter : ICompositeFilter
|
||||
{
|
||||
public bool? And { get; set; }
|
||||
public FilterType Type { get; set; } = FilterType.Composite;
|
||||
public List<IFilter> Filters { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using PoweredSoft.DynamicQuery.Core;
|
||||
|
||||
namespace PoweredSoft.DynamicQuery
|
||||
{
|
||||
public class Group : IGroup
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public bool? Ascending { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\DynamicLinq\PoweredSoft.DynamicLinq\PoweredSoft.DynamicLinq.csproj" />
|
||||
<ProjectReference Include="..\PoweredSoft.DynamicQuery.Core\PoweredSoft.DynamicQuery.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
using PoweredSoft.DynamicQuery.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PoweredSoft.DynamicQuery
|
||||
{
|
||||
public class QueryBuilder : IQueryBuilder
|
||||
{
|
||||
protected List<IQueryInterceptor> Interceptors { get; } = new List<IQueryInterceptor>();
|
||||
protected IQueryCriteria Criteria { get; set; }
|
||||
protected IQueryable QueryableAtStart { get; private set; }
|
||||
protected IQueryable CurrentQueryable { get; set; }
|
||||
protected Type QueryableUnderlyingType => QueryableAtStart.ElementType;
|
||||
private MethodInfo ApplyInterceptorsAndCriteriaMethod { get; } = typeof(QueryBuilder).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).First(t => t.Name == "ApplyInterceptorsAndCriteria" && t.IsGenericMethod);
|
||||
|
||||
protected virtual void Reset(IQueryable queryable, IQueryCriteria criteria)
|
||||
{
|
||||
//Criteria = criteria ?? throw new ArgumentNullException("criteria");
|
||||
QueryableAtStart = queryable ?? throw new ArgumentNullException("queryable");
|
||||
CurrentQueryable = QueryableAtStart;
|
||||
}
|
||||
|
||||
public virtual void AddInterceptor(IQueryInterceptor interceptor)
|
||||
{
|
||||
if (interceptor == null) throw new ArgumentNullException("interceptor");
|
||||
|
||||
if (!Interceptors.Contains(interceptor))
|
||||
Interceptors.Add(interceptor);
|
||||
}
|
||||
|
||||
protected virtual void ApplyInterceptorsAndCriteria<T>()
|
||||
{
|
||||
ApplySimpleBeforeAlterInterceptors();
|
||||
ApplyGenericBeforeAlterInterceptors<T>();
|
||||
}
|
||||
|
||||
private void ApplyInterceptorsAndCriteria()
|
||||
{
|
||||
var genericMethod = ApplyInterceptorsAndCriteriaMethod.MakeGenericMethod(QueryableUnderlyingType);
|
||||
genericMethod.Invoke(this, null);
|
||||
}
|
||||
|
||||
protected virtual void ApplyGenericBeforeAlterInterceptors<T>()
|
||||
{
|
||||
var interceptors = Interceptors.Where(t => t is IBeforeQueryAlteredInterceptor<T>).Cast<IBeforeQueryAlteredInterceptor<T>>().ToList();
|
||||
interceptors.ForEach(i => CurrentQueryable = i.InterceptQueryBeforeAltered(Criteria, (IQueryable<T>)CurrentQueryable));
|
||||
}
|
||||
|
||||
protected virtual void ApplySimpleBeforeAlterInterceptors()
|
||||
{
|
||||
var beforeAlterInterceptors = Interceptors.Where(t => t is IBeforeQueryAlteredInterceptor).Cast<IBeforeQueryAlteredInterceptor>().ToList();
|
||||
beforeAlterInterceptors.ForEach(i => CurrentQueryable = i.InterceptQueryBeforeAltered(Criteria, CurrentQueryable));
|
||||
}
|
||||
|
||||
public virtual IQueryResult Execute(IQueryable queryable, IQueryCriteria criteria)
|
||||
{
|
||||
Reset(queryable, criteria);
|
||||
ApplyInterceptorsAndCriteria();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public virtual Task<IQueryResult> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using PoweredSoft.DynamicQuery.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace PoweredSoft.DynamicQuery
|
||||
{
|
||||
public class QueryCriteria : IQueryCriteria
|
||||
{
|
||||
public int? Page { get; set; }
|
||||
public int? PageSize { get; set; }
|
||||
public List<ISort> Sorts { get; set; } = new List<ISort>();
|
||||
public List<IFilter> Filters { get; set; } = new List<IFilter>();
|
||||
public List<IGroup> Groups { get; set; } = new List<IGroup>();
|
||||
public List<IAggregate> Aggregates { get; set; } = new List<IAggregate>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
using PoweredSoft.DynamicQuery.Core;
|
||||
using PoweredSoft.DynamicLinq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using PoweredSoft.DynamicLinq.Fluent;
|
||||
using PoweredSoft.DynamicQuery.Extensions;
|
||||
|
||||
namespace PoweredSoft.DynamicQuery
|
||||
{
|
||||
public class QueryHandler : IQueryHandler
|
||||
{
|
||||
protected List<IQueryInterceptor> Interceptors { get; } = new List<IQueryInterceptor>();
|
||||
protected IQueryCriteria Criteria { get; set; }
|
||||
protected IQueryable QueryableAtStart { get; private set; }
|
||||
protected IQueryable CurrentQueryable { get; set; }
|
||||
protected Type QueryableUnderlyingType => QueryableAtStart.ElementType;
|
||||
private MethodInfo ApplyInterceptorsAndCriteriaMethod { get; } = typeof(QueryHandler).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).First(t => t.Name == "ApplyInterceptorsAndCriteria" && t.IsGenericMethod);
|
||||
|
||||
protected virtual void Reset(IQueryable queryable, IQueryCriteria criteria)
|
||||
{
|
||||
Criteria = criteria ?? throw new ArgumentNullException("criteria");
|
||||
QueryableAtStart = queryable ?? throw new ArgumentNullException("queryable");
|
||||
CurrentQueryable = QueryableAtStart;
|
||||
}
|
||||
|
||||
public virtual void AddInterceptor(IQueryInterceptor interceptor)
|
||||
{
|
||||
if (interceptor == null) throw new ArgumentNullException("interceptor");
|
||||
|
||||
if (!Interceptors.Contains(interceptor))
|
||||
Interceptors.Add(interceptor);
|
||||
}
|
||||
|
||||
protected virtual void ApplyInterceptorsAndCriteria<T>()
|
||||
{
|
||||
ApplySimpleBeforeAlterInterceptors();
|
||||
ApplyGenericBeforeAlterInterceptors<T>();
|
||||
ApplyFilters<T>();
|
||||
}
|
||||
|
||||
protected virtual ConditionOperators? ResolveFromOrDefault(FilterType filterType) =>
|
||||
filterType.ConditionOperator();
|
||||
|
||||
protected virtual ConditionOperators ResolveFrom(FilterType filterType)
|
||||
{
|
||||
var ret = ResolveFromOrDefault(filterType);
|
||||
if (ret == null)
|
||||
throw new NotSupportedException($"{filterType} is not supported");
|
||||
|
||||
return ret.Value;
|
||||
}
|
||||
|
||||
protected virtual void ApplyFilters<T>()
|
||||
{
|
||||
CurrentQueryable = CurrentQueryable.Query(whereBuilder =>
|
||||
{
|
||||
Criteria.Filters.ForEach(filter => ApplyFilter(whereBuilder, filter));
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual void ApplyFilter(WhereBuilder whereBuilder, IFilter filter)
|
||||
{
|
||||
var transformedFilter = InterceptFilter(filter);
|
||||
if (transformedFilter is ISimpleFilter)
|
||||
ApplySimpleFilter(whereBuilder, transformedFilter as ISimpleFilter);
|
||||
else if (transformedFilter is ICompositeFilter)
|
||||
AppleCompositeFilter(whereBuilder, transformedFilter as ICompositeFilter);
|
||||
else
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
protected virtual void AppleCompositeFilter(WhereBuilder whereBuilder, ICompositeFilter filter)
|
||||
{
|
||||
whereBuilder.SubQuery(subWhereBuilder => filter.Filters.ForEach(subFilter => ApplyFilter(subWhereBuilder, subFilter)), filter.And == true);
|
||||
}
|
||||
|
||||
protected virtual void ApplySimpleFilter(WhereBuilder whereBuilder, ISimpleFilter filter)
|
||||
{
|
||||
var resolvedConditionOperator = ResolveFrom(filter.Type);
|
||||
whereBuilder.Compare(filter.Path, resolvedConditionOperator, filter.Value, and: filter.And == true);
|
||||
}
|
||||
|
||||
private IFilter InterceptFilter(IFilter filter)
|
||||
{
|
||||
var ret = Interceptors.Where(t => t is IFilterInterceptor)
|
||||
.Cast<IFilterInterceptor>()
|
||||
.Aggregate(filter, (previousFilter, interceptor) => interceptor.InterceptFilter(previousFilter));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void ApplyInterceptorsAndCriteria()
|
||||
{
|
||||
var genericMethod = ApplyInterceptorsAndCriteriaMethod.MakeGenericMethod(QueryableUnderlyingType);
|
||||
genericMethod.Invoke(this, null);
|
||||
}
|
||||
|
||||
protected virtual void ApplyGenericBeforeAlterInterceptors<T>()
|
||||
{
|
||||
CurrentQueryable = Interceptors
|
||||
.Where(t => t is IBeforeQueryAlteredInterceptor<T>)
|
||||
.Cast<IBeforeQueryAlteredInterceptor<T>>()
|
||||
.Aggregate((IQueryable<T>)CurrentQueryable, (prev, interceptor) => interceptor.InterceptQueryBeforeAltered(Criteria, prev));
|
||||
}
|
||||
|
||||
protected virtual void ApplySimpleBeforeAlterInterceptors()
|
||||
{
|
||||
CurrentQueryable = Interceptors
|
||||
.Where(t => t is IBeforeQueryAlteredInterceptor)
|
||||
.Cast<IBeforeQueryAlteredInterceptor>()
|
||||
.Aggregate(CurrentQueryable, (prev, interceptor) => interceptor.InterceptQueryBeforeAltered(Criteria, prev));
|
||||
}
|
||||
|
||||
public virtual IQueryResult Execute(IQueryable queryable, IQueryCriteria criteria)
|
||||
{
|
||||
Reset(queryable, criteria);
|
||||
ApplyInterceptorsAndCriteria();
|
||||
var debug = CurrentQueryable.ToObjectList();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public virtual Task<IQueryResult> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using PoweredSoft.DynamicQuery.Core;
|
||||
|
||||
namespace PoweredSoft.DynamicQuery
|
||||
{
|
||||
public class Sort : ISort
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public bool? Ascending { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user