Add project files.
This commit is contained in:
parent
d906a5e7d4
commit
d2d28a9a45
37
DynamicQuery.sln
Normal file
37
DynamicQuery.sln
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.28010.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.DynamicQuery.Core", "PoweredSoft.DynamicQuery.Core\PoweredSoft.DynamicQuery.Core.csproj", "{E614658D-6852-4405-B5BE-3695C3E96B13}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.DynamicQuery", "PoweredSoft.DynamicQuery\PoweredSoft.DynamicQuery.csproj", "{A9F74387-6B09-423A-96BC-F8FF345193EE}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.DynamicQuery.Cli", "PoweredSoft.DynamicQuery.Cli\PoweredSoft.DynamicQuery.Cli.csproj", "{7FC0F790-A8B9-4335-8D72-09797DEB0359}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E614658D-6852-4405-B5BE-3695C3E96B13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E614658D-6852-4405-B5BE-3695C3E96B13}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E614658D-6852-4405-B5BE-3695C3E96B13}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E614658D-6852-4405-B5BE-3695C3E96B13}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A9F74387-6B09-423A-96BC-F8FF345193EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A9F74387-6B09-423A-96BC-F8FF345193EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A9F74387-6B09-423A-96BC-F8FF345193EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A9F74387-6B09-423A-96BC-F8FF345193EE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{7FC0F790-A8B9-4335-8D72-09797DEB0359}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{7FC0F790-A8B9-4335-8D72-09797DEB0359}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7FC0F790-A8B9-4335-8D72-09797DEB0359}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{7FC0F790-A8B9-4335-8D72-09797DEB0359}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {3770CB3C-28E4-4C15-A537-4DA38CFBA4F3}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\PoweredSoft.DynamicQuery.Core\PoweredSoft.DynamicQuery.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\PoweredSoft.DynamicQuery\PoweredSoft.DynamicQuery.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
47
PoweredSoft.DynamicQuery.Cli/Program.cs
Normal file
47
PoweredSoft.DynamicQuery.Cli/Program.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using PoweredSoft.DynamicQuery.Core;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace PoweredSoft.DynamicQuery.Cli
|
||||||
|
{
|
||||||
|
public class PersonQueryInterceptor : IBeforeQueryAlteredInterceptor<Person>
|
||||||
|
{
|
||||||
|
public IQueryable<Person> InterceptQueryBeforeAltered(IQueryCriteria criteria, IQueryable<Person> queryable) => queryable.Where(t => t.FirstName == "David");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Person
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string FirstName { get; set; }
|
||||||
|
public string LastName { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Play1();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Play1()
|
||||||
|
{
|
||||||
|
var list = new List<Person>()
|
||||||
|
{
|
||||||
|
new Person{ Id = 1, FirstName = "David", LastName = "Lebee "},
|
||||||
|
new Person{ Id = 2, FirstName = "Michaela", LastName = "Lebee "},
|
||||||
|
new Person{ Id = 3, FirstName = "Zohra", LastName = "Lebee "},
|
||||||
|
new Person{ Id = 4, FirstName = "Eric", LastName = "Vickar "},
|
||||||
|
new Person{ Id = 5, FirstName = "Susan", LastName = "Vickar "},
|
||||||
|
};
|
||||||
|
|
||||||
|
var queryable = list.AsQueryable();
|
||||||
|
|
||||||
|
var qb = new QueryBuilder();
|
||||||
|
qb.AddInterceptor(new PersonQueryInterceptor());
|
||||||
|
qb.Execute(queryable, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
PoweredSoft.DynamicQuery.Core/AggregateType.cs
Normal file
11
PoweredSoft.DynamicQuery.Core/AggregateType.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public enum AggregateType
|
||||||
|
{
|
||||||
|
Count,
|
||||||
|
Sum,
|
||||||
|
Avg,
|
||||||
|
Max,
|
||||||
|
Min
|
||||||
|
}
|
||||||
|
}
|
11
PoweredSoft.DynamicQuery.Core/FilterType.cs
Normal file
11
PoweredSoft.DynamicQuery.Core/FilterType.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public enum FilterType
|
||||||
|
{
|
||||||
|
Equals,
|
||||||
|
Contains,
|
||||||
|
StartsWith,
|
||||||
|
EndsWith,
|
||||||
|
Composite
|
||||||
|
}
|
||||||
|
}
|
8
PoweredSoft.DynamicQuery.Core/IAggregate.cs
Normal file
8
PoweredSoft.DynamicQuery.Core/IAggregate.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public interface IAggregate
|
||||||
|
{
|
||||||
|
string Path { get; set; }
|
||||||
|
AggregateType Type { get; set; }
|
||||||
|
}
|
||||||
|
}
|
9
PoweredSoft.DynamicQuery.Core/ICompositeFilter.cs
Normal file
9
PoweredSoft.DynamicQuery.Core/ICompositeFilter.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public interface ICompositeFilter : IFilter
|
||||||
|
{
|
||||||
|
List<IFilter> Filters { get; set; }
|
||||||
|
}
|
||||||
|
}
|
8
PoweredSoft.DynamicQuery.Core/IFilter.cs
Normal file
8
PoweredSoft.DynamicQuery.Core/IFilter.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public interface IFilter
|
||||||
|
{
|
||||||
|
bool? And { get; set; }
|
||||||
|
FilterType Type { get; set; }
|
||||||
|
}
|
||||||
|
}
|
8
PoweredSoft.DynamicQuery.Core/IGroup.cs
Normal file
8
PoweredSoft.DynamicQuery.Core/IGroup.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public interface IGroup
|
||||||
|
{
|
||||||
|
string Path { get; set; }
|
||||||
|
bool? Ascending { get; set; }
|
||||||
|
}
|
||||||
|
}
|
55
PoweredSoft.DynamicQuery.Core/IQueryBuilder.cs
Normal file
55
PoweredSoft.DynamicQuery.Core/IQueryBuilder.cs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public interface IQueryBuilder
|
||||||
|
{
|
||||||
|
IQueryResult Execute(IQueryable queryable, IQueryCriteria criteria);
|
||||||
|
Task<IQueryResult> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria);
|
||||||
|
void AddInterceptor(IQueryInterceptor interceptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IQueryInterceptor
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IBeforeQueryAlteredInterceptor : IQueryInterceptor
|
||||||
|
{
|
||||||
|
IQueryable InterceptQueryBeforeAltered(IQueryCriteria criteria, IQueryable queryable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IBeforeQueryAlteredInterceptor<T> : IQueryInterceptor
|
||||||
|
{
|
||||||
|
IQueryable<T> InterceptQueryBeforeAltered(IQueryCriteria criteria, IQueryable<T> queryable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IFilterInteceptor : IQueryInterceptor
|
||||||
|
{
|
||||||
|
IEnumerable<IFilter> InterceptFilter(IFilter filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IGroupingInteceptor : IQueryInterceptor
|
||||||
|
{
|
||||||
|
IGroup InterceptGroup(IGroup group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ISortInteceptor : IQueryInterceptor
|
||||||
|
{
|
||||||
|
IEnumerable<ISort> InterceptSort(ISort sort);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IBeforeQueryExecuteInterceptor : IQueryInterceptor
|
||||||
|
{
|
||||||
|
IQueryable InterceptBeforeQuery(IQueryCriteria criteria, IQueryable queryable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IBeforeQueryExecuteInterceptor<T> : IQueryInterceptor
|
||||||
|
{
|
||||||
|
IQueryable<T> InterceptBeforeQuery(IQueryCriteria criteria, IQueryable<T> queryable);
|
||||||
|
}
|
||||||
|
}
|
16
PoweredSoft.DynamicQuery.Core/IQueryCriteria.cs
Normal file
16
PoweredSoft.DynamicQuery.Core/IQueryCriteria.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public interface IQueryCriteria
|
||||||
|
{
|
||||||
|
int? Page { get; set; }
|
||||||
|
int? PageSize { get; set; }
|
||||||
|
List<ISort> Sorts { get; set; }
|
||||||
|
List<IFilter> Filters { get; set; }
|
||||||
|
List<IGroup> Groups { get; set; }
|
||||||
|
List<IAggregate> Aggregates { get; set; }
|
||||||
|
}
|
||||||
|
}
|
29
PoweredSoft.DynamicQuery.Core/IQueryResult.cs
Normal file
29
PoweredSoft.DynamicQuery.Core/IQueryResult.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public interface IAggregateResult
|
||||||
|
{
|
||||||
|
string Path { get; set; }
|
||||||
|
AggregateType Type { get; set; }
|
||||||
|
object Value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IQueryResult
|
||||||
|
{
|
||||||
|
long Count { get; }
|
||||||
|
List<IAggregateResult> Aggregates { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IQueryResultSimple : IQueryResult
|
||||||
|
{
|
||||||
|
List<object> Data { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IQueryResultGrouped : IQueryResult
|
||||||
|
{
|
||||||
|
List<IQueryResult> Data { get; }
|
||||||
|
}
|
||||||
|
}
|
8
PoweredSoft.DynamicQuery.Core/ISimpleFilter.cs
Normal file
8
PoweredSoft.DynamicQuery.Core/ISimpleFilter.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public interface ISimpleFilter : IFilter
|
||||||
|
{
|
||||||
|
string Path { get; set; }
|
||||||
|
object Value { get; set; }
|
||||||
|
}
|
||||||
|
}
|
8
PoweredSoft.DynamicQuery.Core/ISort.cs
Normal file
8
PoweredSoft.DynamicQuery.Core/ISort.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace PoweredSoft.DynamicQuery.Core
|
||||||
|
{
|
||||||
|
public interface ISort
|
||||||
|
{
|
||||||
|
string Path { get; set; }
|
||||||
|
bool? Ascending { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
11
PoweredSoft.DynamicQuery/PoweredSoft.DynamicQuery.csproj
Normal file
11
PoweredSoft.DynamicQuery/PoweredSoft.DynamicQuery.csproj
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\PoweredSoft.DynamicQuery.Core\PoweredSoft.DynamicQuery.Core.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
72
PoweredSoft.DynamicQuery/QueryBuilder.cs
Normal file
72
PoweredSoft.DynamicQuery/QueryBuilder.cs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user