439 lines
19 KiB
C#
439 lines
19 KiB
C#
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<T>
|
|
{
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>p == null
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> Null(string propertyName)
|
|
{
|
|
return p => p.GetType().GetProperty(propertyName).GetValue(p) == null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>true
|
|
/// </summary>p != null
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>zhangsansss
|
|
public static Expression<Func<T, bool>> NotNull(string propertyName)
|
|
{
|
|
return p => p.GetType().GetProperty(propertyName).GetValue(p) != null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>true
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> True()
|
|
{
|
|
return p => true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>false
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> False()
|
|
{
|
|
return p => false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>p.propertyName
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <param name="sort"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, TKey>> GetOrderExpression<TKey>(string propertyName)
|
|
{
|
|
ParameterExpression param = Expression.Parameter(typeof(T), "t");
|
|
|
|
return Expression.Lambda<Func<T, TKey>>
|
|
(
|
|
Expression.Convert(Expression.Property(param, propertyName),
|
|
typeof(object)),
|
|
param
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>p.propertyName == propertyValue
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="column"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.Equal(member, constant), parameter);
|
|
|
|
return MyEqual(member,constant,parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>p.propertyName != propertyValue
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="propertyName"></param>
|
|
/// <param name="propertyValue"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.NotEqual(member, constant), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式: p=>propertyValue.Contains(p.propertyName) 目前仅支持 List<string>类型,后期完善
|
|
/// </summary>
|
|
/// <param name="propertyName"></param>
|
|
/// <param name="propertyValue"></param>
|
|
/// <returns></returns>
|
|
internal static Expression<Func<T, bool>> GetIn(string propertyName, object propertyValue)
|
|
{
|
|
//目前仅支持 List<string>类型,后期完善
|
|
try
|
|
{
|
|
//使用Newtonsoft的ToObject方法将JArray转换成List<string>类型
|
|
List<string> lst = ((dynamic)propertyValue).ToObject<List<string>>();
|
|
|
|
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
|
|
MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
|
|
|
|
MethodInfo method = typeof(List<string>).GetMethod("Contains", new[] { typeof(string) });
|
|
ConstantExpression constant = Expression.Constant(lst, typeof(List<string>));
|
|
return Expression.Lambda<Func<T, bool>>(Expression.Call(constant, method, member), parameter);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception("查询的参数不合法,无法解析成表达式目录树");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>p.propertyName > propertyValue
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="column"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.GreaterThan(member, constant), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>p.propertyName < propertyValue
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="column"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.LessThan(member, constant), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>p.propertyName >= propertyValue
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="column"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>p.propertyName <= propertyValue
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="column"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.LessThanOrEqual(member, constant), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:p=>p.propertyName.Contains(propertyValue)
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="column"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.Call(member, method, constant), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:!(p=>p.propertyName.Contains(propertyValue))
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="column"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:!(p=>p.propertyName.StartsWith(propertyValue))
|
|
/// </summary>
|
|
/// <param name="propertyName"></param>
|
|
/// <param name="propertyValue"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建lambda表达式:!(p=>p.propertyName.EndsWith(propertyValue))
|
|
/// </summary>
|
|
/// <param name="propertyName"></param>
|
|
/// <param name="propertyValue"></param>
|
|
/// <returns></returns>
|
|
public static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 统一参数类型(值大小比较方法中只支持int和DateTime类型,但上端传递过来的参数有可能为string类型,故需要使用反射的方式统一参数类型)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 判断可空类型
|
|
/// </summary>
|
|
/// <param name="theType"></param>
|
|
/// <returns></returns>
|
|
private static bool IsNullableType(Type theType)
|
|
{
|
|
return (theType.IsGenericType && theType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自定义小于比较
|
|
/// </summary>
|
|
/// <param name="e1"></param>
|
|
/// <param name="e2"></param>
|
|
/// <param name="parameter"></param>
|
|
/// <returns></returns>
|
|
private static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.GreaterThan(e1, e2), parameter);
|
|
}
|
|
|
|
private static Expression<Func<T,bool>> 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<Func<T, bool>>(Expression.Equal(e1, e2), parameter);
|
|
}
|
|
|
|
private static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.Equal(e1, e2), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自定义大于比较
|
|
/// </summary>
|
|
/// <param name="e1"></param>
|
|
/// <param name="e2"></param>
|
|
/// <param name="parameter"></param>
|
|
/// <returns></returns>
|
|
private static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.LessThan(e1, e2), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自定义大于等于比较
|
|
/// </summary>
|
|
/// <param name="e1"></param>
|
|
/// <param name="e2"></param>
|
|
/// <param name="parameter"></param>
|
|
/// <returns></returns>
|
|
private static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.GreaterThanOrEqual(e1, e2), parameter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自定义小于等于比较
|
|
/// </summary>
|
|
/// <param name="e1"></param>
|
|
/// <param name="e2"></param>
|
|
/// <param name="parameter"></param>
|
|
/// <returns></returns>
|
|
private static Expression<Func<T, bool>> 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<Func<T, bool>>(Expression.LessThanOrEqual(e1, e2), parameter);
|
|
}
|
|
}
|
|
}
|