using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Core.Enums;
using WIDESEA_Core.Helper;
namespace WIDESEA_Core.Utilities
{
public static class LambdaExtensions
{
///
///
///
///
/// 字段名
/// 表达式的值
/// 创建表达式的类型,如:p=>p.propertyName != propertyValue
/// p=>p.propertyName.Contains(propertyValue)
///
public static Expression> CreateExpression(this string propertyName, object propertyValue, LinqExpressionType expressionType)
{
return propertyName.CreateExpression(propertyValue, null, expressionType);
}
public static Expression> GetWhereExpression(this PropertyInfo propertyInfo, object propertyValue, ParameterExpression parameter, LinqExpressionType expressionType)
{
Type proType = propertyInfo.PropertyType;
ConstantExpression constant = proType.ToString() == "System.String"
? Expression.Constant(propertyValue) : Expression.Constant(propertyValue.ToString().ChangeType(proType));
// DateTime只选择了日期的时候自动在结束日期加一天,修复DateTime类型使用日期区间查询无法查询到结束日期的问题
if ((proType == typeof(DateTime) || proType == typeof(DateTime?)) && expressionType == LinqExpressionType.LessThanOrEqual && propertyValue.ToString().Length == 10)
{
constant = Expression.Constant(Convert.ToDateTime(propertyValue.ToString()).AddDays(1));
}
parameter = parameter ?? Expression.Parameter(typeof(TEntity), "b");
//创建节点的属性p=>p.name 属性name
MemberExpression memberProperty = Expression.PropertyOrField(parameter, propertyInfo.Name);
UnaryExpression member = Expression.Convert(memberProperty, constant.Type);
Expression> expression = p => false;
switch (expressionType)
{
//p=>p.propertyName == propertyValue
case LinqExpressionType.Equal:
expression = Expression.Lambda>(Expression.Equal(member, constant), parameter);
break;
//p=>p.propertyName != propertyValue
case LinqExpressionType.NotEqual:
expression = Expression.Lambda>(Expression.NotEqual(member, constant), parameter);
break;
// p => p.propertyName > propertyValue
case LinqExpressionType.GreaterThan:
expression = Expression.Lambda>(Expression.GreaterThan(member, constant), parameter);
break;
// p => p.propertyName < propertyValue
case LinqExpressionType.LessThan:
expression = Expression.Lambda>(Expression.LessThan(member, constant), parameter);
break;
// p => p.propertyName >= propertyValue
case LinqExpressionType.ThanOrEqual:
expression = Expression.Lambda>(Expression.GreaterThanOrEqual(member, constant), parameter);
break;
// p => p.propertyName <= propertyValue
case LinqExpressionType.LessThanOrEqual:
expression = Expression.Lambda>(Expression.LessThanOrEqual(member, constant), parameter);
break;
// p => p.propertyName.Contains(propertyValue)
// p => !p.propertyName.Contains(propertyValue)
case LinqExpressionType.Contains:
case LinqExpressionType.NotContains:
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
constant = Expression.Constant(propertyValue, typeof(string));
if (expressionType == LinqExpressionType.Contains)
{
expression = Expression.Lambda>(Expression.Call(member, method, constant), parameter);
}
else
{
expression = Expression.Lambda>(Expression.Not(Expression.Call(member, method, constant)), parameter);
}
break;
default:
//
expression = p => false;
break;
}
return expression;
}
///
///
///
///
/// 字段名
/// 表达式的值
/// 创建表达式的类型,如:p=>p.propertyName != propertyValue
/// p=>p.propertyName.Contains(propertyValue)
///
private static Expression> CreateExpression(
this string propertyName,
object propertyValue,
ParameterExpression parameter,
LinqExpressionType expressionType)
{
Type proType = null;
PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName);
if (propertyInfo != null)
proType = propertyInfo.PropertyType;
else
{
propertyInfo = typeof(T).GetProperty(propertyName.FirstLetterToLower());
if (propertyInfo != null)
proType = propertyInfo.PropertyType;
else
{
propertyInfo = typeof(T).GetProperty(propertyName.FirstLetterToUpper());
if (propertyInfo != null)
proType = propertyInfo.PropertyType;
else
{
throw new Exception($"未找到该属性,type:{typeof(T)}");
}
}
}
//创建节点变量如p=>的节点p
// parameter ??= Expression.Parameter(typeof(T), "p");//创建参数p
parameter = parameter ?? Expression.Parameter(typeof(T), "p");
//创建节点的属性p=>p.name 属性name
MemberExpression memberProperty = Expression.PropertyOrField(parameter, propertyName);
if (expressionType == LinqExpressionType.In)
{
if (!(propertyValue is System.Collections.IList list) || list.Count == 0) throw new Exception("属性值类型不正确");
bool isStringValue = true;
List