|
@@ -0,0 +1,163 @@
|
|
|
+using System;
|
|
|
+using System.Collections.ObjectModel;
|
|
|
+using System.Linq.Expressions;
|
|
|
+using System.Reflection;
|
|
|
+
|
|
|
+namespace wispro.sp.utility
|
|
|
+{
|
|
|
+ public class Query
|
|
|
+ {
|
|
|
+ public enum Operators
|
|
|
+ {
|
|
|
+ None = 0,
|
|
|
+ Equal = 1,
|
|
|
+ GreaterThan = 2,
|
|
|
+ GreaterThanOrEqual = 3,
|
|
|
+ LessThan = 4,
|
|
|
+ LessThanOrEqual = 5,
|
|
|
+ Contains = 6,
|
|
|
+ StartWith = 7,
|
|
|
+ EndWidth = 8,
|
|
|
+ Range = 9
|
|
|
+ }
|
|
|
+ public enum Condition
|
|
|
+ {
|
|
|
+ OrElse = 1,
|
|
|
+ AndAlso = 2
|
|
|
+ }
|
|
|
+ public string Name { get; set; }
|
|
|
+ public Operators Operator { get; set; }
|
|
|
+ public object Value { get; set; }
|
|
|
+ public object ValueMin { get; set; }
|
|
|
+ public object ValueMax { get; set; }
|
|
|
+
|
|
|
+ public class QueryCollection : Collection<Query>
|
|
|
+ {
|
|
|
+ public Expression<Func<T, bool>> AsExpression<T>(Query.Condition? condition = Query.Condition.OrElse) where T : class
|
|
|
+ {
|
|
|
+ Type targetType = typeof(T);
|
|
|
+ TypeInfo typeInfo = targetType.GetTypeInfo();
|
|
|
+ var parameter = Expression.Parameter(targetType, "m");
|
|
|
+ Expression expression = null;
|
|
|
+ Func<Expression, Expression, Expression> Append = (exp1, exp2) =>
|
|
|
+ {
|
|
|
+ if (exp1 == null)
|
|
|
+ {
|
|
|
+ return exp2;
|
|
|
+ }
|
|
|
+ return (condition ?? Query.Condition.OrElse) == Query.Condition.OrElse ? Expression.OrElse(exp1, exp2) : Expression.AndAlso(exp1, exp2);
|
|
|
+ };
|
|
|
+ foreach (var item in this)
|
|
|
+ {
|
|
|
+ var property = typeInfo.GetProperty(item.Name);
|
|
|
+ if (property == null ||
|
|
|
+ !property.CanRead ||
|
|
|
+ (item.Operator != Query.Operators.Range && item.Value == null) ||
|
|
|
+ (item.Operator == Query.Operators.Range && item.ValueMin == null && item.ValueMax == null))
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Type realType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
|
|
|
+ if (item.Value != null)
|
|
|
+ {
|
|
|
+ item.Value = Convert.ChangeType(item.Value, realType);
|
|
|
+ }
|
|
|
+ Expression<Func<object>> valueLamba = () => item.Value;
|
|
|
+ switch (item.Operator)
|
|
|
+ {
|
|
|
+ case Query.Operators.Equal:
|
|
|
+ {
|
|
|
+ expression = Append(expression, Expression.Equal(Expression.Property(parameter, item.Name),
|
|
|
+ Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Query.Operators.GreaterThan:
|
|
|
+ {
|
|
|
+ expression = Append(expression, Expression.GreaterThan(Expression.Property(parameter, item.Name),
|
|
|
+ Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Query.Operators.GreaterThanOrEqual:
|
|
|
+ {
|
|
|
+ expression = Append(expression, Expression.GreaterThanOrEqual(Expression.Property(parameter, item.Name),
|
|
|
+ Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Query.Operators.LessThan:
|
|
|
+ {
|
|
|
+ expression = Append(expression, Expression.LessThan(Expression.Property(parameter, item.Name),
|
|
|
+ Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Query.Operators.LessThanOrEqual:
|
|
|
+ {
|
|
|
+ expression = Append(expression, Expression.LessThanOrEqual(Expression.Property(parameter, item.Name),
|
|
|
+ Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Query.Operators.Contains:
|
|
|
+ {
|
|
|
+ var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name)));
|
|
|
+ var contains = Expression.Call(Expression.Property(parameter, item.Name), "Contains", null,
|
|
|
+ Expression.Convert(valueLamba.Body, property.PropertyType));
|
|
|
+ expression = Append(expression, Expression.AndAlso(nullCheck, contains));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Query.Operators.StartWith:
|
|
|
+ {
|
|
|
+ var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name)));
|
|
|
+ var startsWith = Expression.Call(Expression.Property(parameter, item.Name), "StartsWith", null,
|
|
|
+ Expression.Convert(valueLamba.Body, property.PropertyType));
|
|
|
+ expression = Append(expression, Expression.AndAlso(nullCheck, startsWith));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Query.Operators.EndWidth:
|
|
|
+ {
|
|
|
+ var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name)));
|
|
|
+ var endsWith = Expression.Call(Expression.Property(parameter, item.Name), "EndsWith", null,
|
|
|
+ Expression.Convert(valueLamba.Body, property.PropertyType));
|
|
|
+ expression = Append(expression, Expression.AndAlso(nullCheck, endsWith));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Query.Operators.Range:
|
|
|
+ {
|
|
|
+ Expression minExp = null, maxExp = null;
|
|
|
+ if (item.ValueMin != null)
|
|
|
+ {
|
|
|
+ var minValue = Convert.ChangeType(item.ValueMin, realType);
|
|
|
+ Expression<Func<object>> minValueLamda = () => minValue;
|
|
|
+ minExp = Expression.GreaterThanOrEqual(Expression.Property(parameter, item.Name), Expression.Convert(minValueLamda.Body, property.PropertyType));
|
|
|
+ }
|
|
|
+ if (item.ValueMax != null)
|
|
|
+ {
|
|
|
+ var maxValue = Convert.ChangeType(item.ValueMax, realType);
|
|
|
+ Expression<Func<object>> maxValueLamda = () => maxValue;
|
|
|
+ maxExp = Expression.LessThanOrEqual(Expression.Property(parameter, item.Name), Expression.Convert(maxValueLamda.Body, property.PropertyType));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (minExp != null && maxExp != null)
|
|
|
+ {
|
|
|
+ expression = Append(expression, Expression.AndAlso(minExp, maxExp));
|
|
|
+ }
|
|
|
+ else if (minExp != null)
|
|
|
+ {
|
|
|
+ expression = Append(expression, minExp);
|
|
|
+ }
|
|
|
+ else if (maxExp != null)
|
|
|
+ {
|
|
|
+ expression = Append(expression, maxExp);
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (expression == null)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return ((Expression<Func<T, bool>>)Expression.Lambda(expression, parameter));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|