using System.Linq.Expressions; namespace CmsQueryExtensions.Extension { internal class ParameterRebinder : ExpressionVisitor { private readonly Dictionary map; public ParameterRebinder(Dictionary map) { this.map = map ?? new Dictionary(); } public static Expression ReplaceParameters(Dictionary map, Expression exp) { return new ParameterRebinder(map).Visit(exp); } protected override Expression VisitParameter(ParameterExpression p) { ParameterExpression replacement; if (map.TryGetValue(p, out replacement)) { p = replacement; } return base.VisitParameter(p); } } internal static class PredicateExtensions { public static Expression> True() { return f => true; } public static Expression> False() { return f => false; } public static Expression Compose(this Expression first, Expression second, Func merge) { // build parameter map (from parameters of second to parameters of first) var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f); // replace parameters in the second lambda expression with parameters from the first var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body); // apply composition of lambda expression bodies to parameters from the first expression return Expression.Lambda(merge(first.Body, secondBody), first.Parameters); } public static Expression> And(this Expression> first, Expression> second) { return first.Compose(second, Expression.And); } public static Expression> Or(this Expression> first, Expression> second) { return first.Compose(second, Expression.Or); } /// /// 拼接成 c.Name.contains("1111")||c.Name.Contains("2222")||c.Name.Contains("3333")) 形式 /// /// /// /// /// public static Expression> GetConditionExpression(string[] options, string fieldName) { ParameterExpression left = Expression.Parameter(typeof(T), "c");//c=> Expression expression = Expression.Constant(false); foreach (var optionName in options) { Expression right = Expression.Call ( Expression.Property(left, typeof(T).GetProperty(fieldName)), //c.DataSourceName typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法 Expression.Constant(optionName) // .Contains(optionName) ); expression = Expression.Or(right, expression);//c.DataSourceName.contain("") || c.DataSourceName.contain("") } Expression> finalExpression = Expression.Lambda>(expression, new ParameterExpression[] { left }); return finalExpression; } /// /// (模糊查询)拼接成 c.Name.contains("1111")||c.Code.Contains("1111")||c.Address.Contains("1111")) 形式 /// /// /// /// /// public static Expression> GetConditionExpressionForFuzzyQuery(string[] fieldNames, string fieldValue) { try { ParameterExpression left = Expression.Parameter(typeof(T), "c");//c=> Expression expression = Expression.Constant(false); foreach (var fieldName in fieldNames) { try { Expression right = Expression.Call ( Expression.Property(left, typeof(T).GetProperty(fieldName)), //c.DataSourceName typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法 Expression.Constant(fieldValue) // .Contains(fieldValue) ); expression = Expression.Or(right, expression);//c.AAA.contain("") || c.BBB.contain("") } catch (Exception ex) { throw new Exception($"参数{fieldName}匹配关键字查询时失败:" + ex.Message); } } Expression> finalExpression = Expression.Lambda>(expression, new ParameterExpression[] { left }); return finalExpression; } catch (Exception) { throw; } } /// /// (精准查询)拼接成 c.Name.equals("1111")||c.Code.equals("1111")||c.Address.equals("1111")) 形式 /// /// /// /// /// public static Expression> GetConditionExpressionForPreciseQuery(string[] fieldNames, string fieldValue) { ParameterExpression left = Expression.Parameter(typeof(T), "c");//c=> Expression expression = Expression.Constant(false); foreach (var fieldName in fieldNames) { Expression right = Expression.Call ( Expression.Property(left, typeof(T).GetProperty(fieldName)), //c.DataSourceName typeof(string).GetMethod("Equals", new Type[] { typeof(string) }),// 反射使用.Equals()方法 Expression.Constant(fieldValue) // .Equals(fieldValue) ); expression = Expression.Or(right, expression);//c.AAA.equals("") || c.BBB.equals("") } Expression> finalExpression = Expression.Lambda>(expression, new ParameterExpression[] { left }); return finalExpression; } public static Expression> GetConditionExpressionForHighFieldByAnd(List hsmList) { var whereHelper = new WhereHelper(); foreach (var field in hsmList) { switch (field.filterMode) { case SearchFilterModeEnum.不等于: whereHelper.NotEqual(field.fieldName, field.fieldValue); break; case SearchFilterModeEnum.大于: whereHelper.GreaterThan(field.fieldName, field.fieldValue); break; case SearchFilterModeEnum.大于等于: whereHelper.GreaterThanOrEqual(field.fieldName, field.fieldValue); break; case SearchFilterModeEnum.小于: whereHelper.LessThan(field.fieldName, field.fieldValue); break; case SearchFilterModeEnum.小于等于: whereHelper.LessThanOrEqual(field.fieldName, field.fieldValue); break; case SearchFilterModeEnum.模糊查询: whereHelper.Contains(field.fieldName, field.fieldValue); break; case SearchFilterModeEnum.精准查询: whereHelper.Equal(field.fieldName, field.fieldValue); break; } } Expression> finalExpression = Expression.Lambda>(whereHelper.filter, new ParameterExpression[] { whereHelper.param }); return finalExpression; } public static Expression> GetConditionExpressionForHighFieldByAnd(List hsmForDatetimeList) { var whereHelper = new WhereHelper(); foreach (var field in hsmForDatetimeList) { whereHelper.GreaterThanOrEqual(field.fieldName, field.start_fieldValue); whereHelper.LessThanOrEqual(field.fieldName, field.end_fieldValue); } Expression> finalExpression = Expression.Lambda>(whereHelper.filter, new ParameterExpression[] { whereHelper.param }); return finalExpression; } /// /// 日期范围OR连接 /// /// /// /// public static Expression> GetConditionExpressionForHighDateTimeRangeFieldByOr(List hsmForDatetimeList) { Expression> finalExpression = null; var whereHelper = new WhereHelper(); foreach (var field in hsmForDatetimeList) { whereHelper.GreaterThanOrEqual(field.fieldName, field.start_fieldValue); whereHelper.LessThanOrEqual(field.fieldName, field.end_fieldValue); finalExpression = Expression.Lambda>(whereHelper.filter, new ParameterExpression[] { whereHelper.param }); finalExpression = finalExpression.Or(finalExpression); } return finalExpression; } } }