using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using AddWhere; namespace LinqDemo { public static class QueryBuilder { public static IQueryBuilder Create() { return new QueryBuilder(); } } class QueryBuilder : IQueryBuilder { private Expression> predicate; Expression> IQueryBuilder.Expression { get { return predicate; } set { predicate = value; } } //public List Parameters { get; set; } public QueryBuilder() { predicate = PredicateExtensions.True(); //Parameters = new List(); } } /// /// 动态查询条件创建者 /// /// public interface IQueryBuilder { Expression> Expression { get; set; } //List Parameters { get; set; } } public static class IQueryBuilderExtensions { /// /// 建立 Between 查询条件 /// /// 实体 /// 动态查询条件创建者 /// 属性 /// 开始值 /// 结束值 /// public static IQueryBuilder Between(this IQueryBuilder q, Expression> property, P from, P to) { var parameter = property.GetParameters(); var constantFrom = Expression.Constant(from); var constantTo = Expression.Constant(to); Type type = typeof(P); Expression nonNullProperty = property.Body; //如果是Nullable类型,则转化成X类型 if (IsNullableType(type)) { type = GetNonNullableType(type); nonNullProperty = Expression.Convert(property.Body, type); } System.Linq.Expressions.BinaryExpression c1=null; System.Linq.Expressions.BinaryExpression c2=null; System.Linq.Expressions.BinaryExpression c=null; if (from != null) c1 = Expression.GreaterThanOrEqual(nonNullProperty, constantFrom); if (to != null) c2 = Expression.LessThanOrEqual(nonNullProperty, constantTo); if(from !=null && to != null) c = Expression.AndAlso(c1, c2); if (from != null && to == null) c = c1; if (from == null && to != null) c = c2; Expression> lambda = Expression.Lambda>(c, parameter); q.Expression = q.Expression.And(lambda); return q; } /// /// 建立 Like ( 模糊 ) 查询条件 /// /// 实体 /// 动态查询条件创建者 /// 属性 /// 查询值 /// #region public static IQueryBuilder Like(this IQueryBuilder q, Expression> property, string value) { value = value.Trim(); if (!string.IsNullOrEmpty(value)) { var parameter = property.GetParameters(); Expression> lambda = null; //MethodCallExpression methodExp = Expression.Call(property.Body, // typeof(string).GetMethod("Contains", new Type[] { typeof(string) }), // Expression.Constant(value) //); var c = typeof(string).GetMethod("IndexOf", new[] { typeof(string) }); MethodCallExpression methodExp = Expression.Call(property.Body, c, Expression.Constant(value) ); var condition = Expression.NotEqual(Expression.Convert(methodExp, typeof(int)), Expression.Constant(-1)); lambda = Expression.Lambda>(condition, parameter); //MethodCallExpression methodExp = Expression.Call(null, typeof(SqlMethods).GetMethod("Like", // new Type[] { typeof(string), typeof(string) }), property.Body, constant); //Expression> lambda = Expression.Lambda>(methodExp, parameter); //Expression> lambda = Expression.Lambda>(methodExp, parameter); q.Expression = q.Expression.And(lambda); } return q; } #endregion /// /// 建立 OrLike ( 模糊 ) 查询条件 /// /// 实体 /// 动态查询条件创建者 /// 属性 /// 查询值 /// private static Expression> OrLike(this IQueryBuilder q, Expression> property, string value) { #region //List Expressions = new List(); var parameter = property.GetParameters(); Expression> lambda = null; if (!string.IsNullOrEmpty(value)) { //var propertyBody = GetMemberExpression(q, property); MethodCallExpression methodExp = Expression.Call(property.Body, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }), Expression.Constant(value) //typeof(LinqToSqlShared).GetMethod("IndexOf", new[] { typeof(string) }), Expression.Constant(value) ); //Expressions.Add(methodExp); //var condition = Expression.GreaterThan(methodExp, Expression.Constant(0)); lambda = Expression.Lambda>(methodExp, parameter); } //Expression> lambda = null; //if (Expressions.Count != 0) //{ // Expression expression = Expressions.Aggregate((e1, e2) => Expression.Or(e1, e2)); // lambda = Expression.Lambda>(expression, parameter); // //q.Expression = q.Expression.And(lambda); //} return lambda; #endregion } private static Expression> OrCharIndex(this IQueryBuilder q, Expression> property, string value) { #region var parameter = property.GetParameters(); Expression> lambda = null; if (!string.IsNullOrEmpty(value)) { var c = typeof(string).GetMethod("IndexOf", new[] { typeof(string) }); MethodCallExpression methodExp = Expression.Call(property.Body, c, Expression.Constant(value) ); var condition = Expression.NotEqual(Expression.Convert(methodExp, typeof(int)), Expression.Constant(-1)); lambda = Expression.Lambda>(condition, parameter); } return lambda; #endregion } /// /// 建立 Equals ( 相等 ) 查询条件 /// /// 实体 /// 动态查询条件创建者 /// 属性 /// 查询值 /// public static IQueryBuilder Equals(this IQueryBuilder q, Expression> property, P value) { var parameter = property.GetParameters(); var constant = Expression.Constant(value); Type type = typeof(P); Expression nonNullProperty = property.Body; //如果是Nullable类型,则转化成X类型 if (IsNullableType(type)) { type = GetNonNullableType(type); nonNullProperty = Expression.Convert(property.Body, type); } var methodExp = Expression.Equal(nonNullProperty, constant); Expression> lambda = Expression.Lambda>(methodExp, parameter); q.Expression = q.Expression.And(lambda); return q; } /// /// 建立 In 查询条件 /// /// 实体 /// 动态查询条件创建者 /// 属性 /// 查询值 /// public static IQueryBuilder In(this IQueryBuilder q, Expression> property, IEnumerable

values) { if (values != null ) { var parameter = property.GetParameters(); var constant = Expression.Constant(values); Type type = typeof(P); Expression nonNullProperty = property.Body; //如果是Nullable类型,则转化成X类型 if (IsNullableType(type)) { type = GetNonNullableType(type); nonNullProperty = Expression.Convert(property.Body, type); } Expression, P, bool>> InExpression = (list, el) => list.Contains(el); var methodExp = InExpression; var invoke = Expression.Invoke(methodExp, constant, property.Body); Expression> lambda = Expression.Lambda>(invoke, parameter); q.Expression = q.Expression.And(lambda); } return q; } ///

/// 建立 NotIn 查询条件 /// /// 实体 /// 动态查询条件创建者 /// 属性 /// 查询值 /// public static IQueryBuilder NotIn(this IQueryBuilder q, Expression> property, IEnumerable

values) { if (values != null ) { var parameter = property.GetParameters(); var constant = Expression.Constant(values); Type type = typeof(P); Expression nonNullProperty = property.Body; //如果是Nullable类型,则转化成X类型 if (IsNullableType(type)) { type = GetNonNullableType(type); nonNullProperty = Expression.Convert(property.Body, type); } Expression, P, bool>> InExpression = (list, el) => !list.Contains(el); var methodExp = InExpression; var invoke = Expression.Invoke(methodExp, constant, property.Body); Expression> lambda = Expression.Lambda>(invoke, parameter); q.Expression = q.Expression.And(lambda); } return q; } ///

/// FullText查询,多字段 多字符串 /// /// /// /// 支持1 2 3 以空格作为分隔符 /// 查询字段属性 o => o.xxx1,o => o.xxx2... /// public static IQueryBuilder FullText(this IQueryBuilder q, string expression, List>> properties) { if (string.IsNullOrEmpty(expression)) return q; if (properties == null || properties.Count() == 0 ) return q; string[] es = expression.Split(' '); List>> lambda1 = new List>>(); foreach (var str in es) { List>> lambda2 = new List>>(); foreach (var property in properties) { var a = q.OrCharIndex(property, str); if(a != null) lambda2.Add(a); } if (lambda2.Count != 0) lambda1.Add(lambda2.Aggregate((e1, e2) => e1.Or(e2))); } //var b = lambda1.Aggregate((e1, e2) => e1.Or(e2)); //q.Expression = q.Expression.And(b); foreach (var b in lambda1) q.Expression = q.Expression.And(b); return q; } private static ParameterExpression[] GetParameters(this Expression> expr) { return expr.Parameters.ToArray(); } static bool IsNullableType(Type type) { return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); } static Type GetNonNullableType(Type type) { return type.GetGenericArguments()[0]; //return IsNullableType(type) ? type.GetGenericArguments()[0] : type; } public static void ForEach(this IEnumerable source, Action action) { foreach (T element in source) action(element); } //EF参数重写 //private static Expression GetMemberExpression(IQueryBuilder q, Expression> property) //{ // if (q.Parameters == null || q.Parameters.Count == 0) // { // property.Parameters.ForEach( // p => // { // q.Parameters.Add(p); // } // ); // return property.Body; // } // ParameterExpressionVisitor visitor = new ParameterExpressionVisitor(q.Parameters[0]); // Expression memberExpr = visitor.ChangeParameter(property.Body); // return memberExpr; //} //public class ParameterExpressionVisitor : ExpressionVisitor //{ // private ParameterExpression newParameterExpression; // public ParameterExpressionVisitor(ParameterExpression p) // { // newParameterExpression = p; // } // public Expression ChangeParameter(Expression exp) // { // return Visit(exp); // } // protected override Expression VisitParameter(ParameterExpression p) // { // return newParameterExpression; // } //} } }