Files
ww-jst/wmsjst/JSMachine.WMS.Infrastructure/LambdaHelp/LambdaHelper.cs
T
2026-09-02 16:31:50 +08:00

389 lines
17 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 LambdaHelper<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");
//MemberExpression body = Expression.Property(param, propertyName);
//return Expression.Lambda<Func<T, TKey>>(Expression.Convert(body, typeof(T).GetProperty(propertyName).PropertyType));
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)
{
var 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 Expression.Lambda<Func<T, bool>>(Expression.Equal(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();
var 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();
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 void UnifyParamType(Type type, ref object param)
{
//param = type.GetMethod("Parse", new Type[] { typeof(string) }).Invoke(param, new object[] { param.ToString() });
if (IsNullableType(type))
{
NullableConverter nullableConverter = new(type);
param = nullableConverter.ConvertFromString(param.ToString());
}
else
{
param = Convert.ChangeType(param, type);
}
}
/// <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);
}
/// <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);
}
}
}