using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq.Expressions; using System.Reflection; namespace JSMachine.WMS.Infrastructure.LambdaHelp { public static class ExpressionTreeHelper { /// /// 创建lambda表达式:p=>p == null /// /// /// public static Expression> Null(string propertyName) { return p => p.GetType().GetProperty(propertyName).GetValue(p) == null; } /// /// 创建lambda表达式:p=>true /// p != null /// /// zhangsansss public static Expression> NotNull(string propertyName) { return p => p.GetType().GetProperty(propertyName).GetValue(p) != null; } /// /// 创建lambda表达式:p=>true /// /// /// public static Expression> True() { return p => true; } /// /// 创建lambda表达式:p=>false /// /// /// public static Expression> False() { return p => false; } /// /// 创建lambda表达式:p=>p.propertyName /// /// /// /// /// public static Expression> GetOrderExpression(string propertyName) { ParameterExpression param = Expression.Parameter(typeof(T), "t"); return Expression.Lambda> ( Expression.Convert(Expression.Property(param, propertyName), typeof(object)), param ); } /// /// 创建lambda表达式:p=>p.propertyName == propertyValue /// /// /// /// /// public static Expression> CreateEqual(string propertyName, object propertyValue) { propertyValue = propertyValue.ToString(); Type type = typeof(T).GetProperty(propertyName).PropertyType; if (!UnifyParamType(type, ref propertyValue)) { return False(); } ////Type type = typeof(T).GetProperty(propertyName).PropertyType; ////propertyValue = propertyValue.ToString(); ////propertyValue = Convert.ChangeType(propertyValue, type); //ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p //MemberExpression member = Expression.PropertyOrField(parameter, propertyName); //ConstantExpression constant = Expression.Constant(propertyValue);//创建常数 //return MyEqual(member, constant, parameter); //propertyValue = propertyValue.ToString(); //propertyValue = Convert.ChangeType(propertyValue, type); ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = Expression.Constant(propertyValue);//创建常数 //return Expression.Lambda>(Expression.Equal(member, constant), parameter); return MyEqual(member,constant,parameter); } /// /// 创建lambda表达式:p=>p.propertyName != propertyValue /// /// /// /// /// public static Expression> CreateNotEqual(string propertyName, object propertyValue) { propertyValue = propertyValue.ToString(); Type type = typeof(T).GetProperty(propertyName).PropertyType; propertyValue = Convert.ChangeType(propertyValue, type); ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = Expression.Constant(propertyValue);//创建常数 return Expression.Lambda>(Expression.NotEqual(member, constant), parameter); } /// /// 创建lambda表达式: p=>propertyValue.Contains(p.propertyName) 目前仅支持 List类型,后期完善 /// /// /// /// internal static Expression> GetIn(string propertyName, object propertyValue) { //目前仅支持 List类型,后期完善 try { //使用Newtonsoft的ToObject方法将JArray转换成List类型 List lst = ((dynamic)propertyValue).ToObject>(); ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); MemberExpression member = Expression.PropertyOrField(parameter, propertyName); MethodInfo method = typeof(List).GetMethod("Contains", new[] { typeof(string) }); ConstantExpression constant = Expression.Constant(lst, typeof(List)); return Expression.Lambda>(Expression.Call(constant, method, member), parameter); } catch (Exception ex) { throw new Exception("查询的参数不合法,无法解析成表达式目录树"); } } /// /// 创建lambda表达式:p=>p.propertyName > propertyValue /// /// /// /// /// public static Expression> CreateGreaterThan(string propertyName, object propertyValue) { propertyValue = propertyValue.ToString(); UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue); ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = Expression.Constant(propertyValue);//创建常数 return MyGreaterThan(member, constant, parameter); //return Expression.Lambda>(Expression.GreaterThan(member, constant), parameter); } /// /// 创建lambda表达式:p=>p.propertyName < propertyValue /// /// /// /// /// public static Expression> CreateLessThan(string propertyName, object propertyValue) { propertyValue = propertyValue.ToString(); UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue); ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = Expression.Constant(propertyValue);//创建常数 return MyLessThan(member, constant, parameter); //return Expression.Lambda>(Expression.LessThan(member, constant), parameter); } /// /// 创建lambda表达式:p=>p.propertyName >= propertyValue /// /// /// /// /// public static Expression> CreateGreaterThanOrEqual(string propertyName, object propertyValue) { propertyValue = propertyValue.ToString(); UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue); ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = Expression.Constant(propertyValue);//创建常数 return MyGreaterThanOrEqual(member, constant, parameter); //return Expression.Lambda>(Expression.GreaterThanOrEqual(member, constant), parameter); } /// /// 创建lambda表达式:p=>p.propertyName <= propertyValue /// /// /// /// /// public static Expression> CreateLessThanOrEqual(string propertyName, object propertyValue) { propertyValue = propertyValue.ToString(); UnifyParamType(typeof(T).GetProperty(propertyName).PropertyType, ref propertyValue); ParameterExpression parameter = Expression.Parameter(typeof(T), "t");//创建参数p MemberExpression member = Expression.PropertyOrField(parameter, propertyName); ConstantExpression constant = Expression.Constant(propertyValue);//创建常数 return MyLessThanOrEqual(member, constant, parameter); //return Expression.Lambda>(Expression.LessThanOrEqual(member, constant), parameter); } /// /// 创建lambda表达式:p=>p.propertyName.Contains(propertyValue) /// /// /// /// /// public static Expression> GetContains(string propertyName, object propertyValue) { propertyValue = propertyValue.ToString(); Type type = typeof(T).GetProperty(propertyName).PropertyType; if (!UnifyParamType(type, ref propertyValue)) { return False(); } ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); MemberExpression member = Expression.PropertyOrField(parameter, propertyName); MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); ConstantExpression constant = Expression.Constant(propertyValue, typeof(string)); return Expression.Lambda>(Expression.Call(member, method, constant), parameter); } /// /// 创建lambda表达式:!(p=>p.propertyName.Contains(propertyValue)) /// /// /// /// /// public static Expression> GetNotContains(string propertyName, object propertyValue) { propertyValue = propertyValue.ToString(); ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); MemberExpression member = Expression.PropertyOrField(parameter, propertyName); MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); ConstantExpression constant = Expression.Constant(propertyValue, typeof(string)); return Expression.Lambda>(Expression.Not(Expression.Call(member, method, constant)), parameter); } /// /// 创建lambda表达式:!(p=>p.propertyName.StartsWith(propertyValue)) /// /// /// /// public static Expression> GetStartsWith(string propertyName, object propertyValue) { propertyValue = propertyValue.ToString(); ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); MemberExpression member = Expression.PropertyOrField(parameter, propertyName); MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); ConstantExpression constant = Expression.Constant(propertyValue, typeof(string)); return Expression.Lambda>(Expression.Not(Expression.Call(member, method, constant)), parameter); } /// /// 创建lambda表达式:!(p=>p.propertyName.EndsWith(propertyValue)) /// /// /// /// public static Expression> GetEndsWith(string propertyName, object propertyValue) { propertyValue = propertyValue.ToString(); ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); MemberExpression member = Expression.PropertyOrField(parameter, propertyName); MethodInfo method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) }); ConstantExpression constant = Expression.Constant(propertyValue, typeof(string)); return Expression.Lambda>(Expression.Not(Expression.Call(member, method, constant)), parameter); } /// /// 统一参数类型(值大小比较方法中只支持int和DateTime类型,但上端传递过来的参数有可能为string类型,故需要使用反射的方式统一参数类型) /// /// private static bool UnifyParamType(Type type, ref object param) { //如果类型转换失败,说明无法转换,比如将字符串 aaa转换为 int类型等 try { if (IsNullableType(type)) { NullableConverter nullableConverter = new(type); param = nullableConverter.ConvertFromString(param.ToString()); } else { //if (type != param.GetType()) param = Convert.ChangeType(param, type); } return true; } catch (Exception ex) { return false; throw ex; } } /// /// 判断可空类型 /// /// /// private static bool IsNullableType(Type theType) { return (theType.IsGenericType && theType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))); } /// /// 自定义小于比较 /// /// /// /// /// private static Expression> MyGreaterThan(Expression e1, Expression e2, ParameterExpression parameter) { if (IsNullableType(e1.Type) && !IsNullableType(e2.Type)) e2 = Expression.Convert(e2, e1.Type); else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type)) e1 = Expression.Convert(e1, e2.Type); return Expression.Lambda>(Expression.GreaterThan(e1, e2), parameter); } private static Expression> MyEqual(Expression e1,Expression e2, ParameterExpression parameter) { if (IsNullableType(e1.Type) && !IsNullableType(e2.Type)) e2 = Expression.Convert(e2, e1.Type); else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type)) e1 = Expression.Convert(e1, e2.Type); return Expression.Lambda>(Expression.Equal(e1, e2), parameter); } private static Expression> MyContains(Expression e1, Expression e2, ParameterExpression parameter) { if (IsNullableType(e1.Type) && !IsNullableType(e2.Type)) e2 = Expression.Convert(e2, e1.Type); else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type)) e1 = Expression.Convert(e1, e2.Type); return Expression.Lambda>(Expression.Equal(e1, e2), parameter); } /// /// 自定义大于比较 /// /// /// /// /// private static Expression> MyLessThan(Expression e1, Expression e2, ParameterExpression parameter) { if (IsNullableType(e1.Type) && !IsNullableType(e2.Type)) e2 = Expression.Convert(e2, e1.Type); else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type)) e1 = Expression.Convert(e1, e2.Type); return Expression.Lambda>(Expression.LessThan(e1, e2), parameter); } /// /// 自定义大于等于比较 /// /// /// /// /// private static Expression> MyGreaterThanOrEqual(Expression e1, Expression e2, ParameterExpression parameter) { if (IsNullableType(e1.Type) && !IsNullableType(e2.Type)) e2 = Expression.Convert(e2, e1.Type); else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type)) e1 = Expression.Convert(e1, e2.Type); return Expression.Lambda>(Expression.GreaterThanOrEqual(e1, e2), parameter); } /// /// 自定义小于等于比较 /// /// /// /// /// private static Expression> MyLessThanOrEqual(Expression e1, Expression e2, ParameterExpression parameter) { if (IsNullableType(e1.Type) && !IsNullableType(e2.Type)) e2 = Expression.Convert(e2, e1.Type); else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type)) e1 = Expression.Convert(e1, e2.Type); return Expression.Lambda>(Expression.LessThanOrEqual(e1, e2), parameter); } } }