| 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 | 
|     { | 
|         /// <summary> | 
|         ///  | 
|         /// </summary> | 
|         /// <typeparam name="T"></typeparam> | 
|         /// <param name="propertyName">字段名</param> | 
|         /// <param name="propertyValue">表达式的值</param> | 
|         /// <param name="expressionType">创建表达式的类型,如:p=>p.propertyName != propertyValue  | 
|         /// p=>p.propertyName.Contains(propertyValue)</param> | 
|         /// <returns></returns> | 
|         public static Expression<Func<T, bool>> CreateExpression<T>(this string propertyName, object propertyValue, LinqExpressionType expressionType) | 
|         { | 
|             return propertyName.CreateExpression<T>(propertyValue, null, expressionType); | 
|         } | 
|   | 
|         /// <summary> | 
|         ///  | 
|         /// </summary> | 
|         /// <typeparam name="T"></typeparam> | 
|         /// <param name="propertyName">字段名</param> | 
|         /// <param name="propertyValue">表达式的值</param> | 
|         /// <param name="expressionType">创建表达式的类型,如:p=>p.propertyName != propertyValue  | 
|         /// p=>p.propertyName.Contains(propertyValue)</param> | 
|         /// <returns></returns> | 
|         private static Expression<Func<T, bool>> CreateExpression<T>( | 
|           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<object> objList = new List<object>(); | 
|   | 
|                 if (proType.ToString() != "System.String") | 
|                 { | 
|                     isStringValue = false; | 
|                     foreach (var value in list) | 
|                     { | 
|                         objList.Add(value.ToString().ChangeType(proType)); | 
|                     } | 
|                     list = objList; | 
|                 } | 
|   | 
|                 if (isStringValue) | 
|                 { | 
|                     //string 类型的字段,如果值带有'单引号,EF会默认变成''两个单引号 | 
|                     MethodInfo method = typeof(System.Collections.IList).GetMethod("Contains"); | 
|                     //创建集合常量并设置为常量的值 | 
|                     ConstantExpression constantCollection = Expression.Constant(list); | 
|                     //创建一个表示调用带参数的方法的:new string[]{"1","a"}.Contains("a"); | 
|                     MethodCallExpression methodCall = Expression.Call(constantCollection, method, memberProperty); | 
|                     return Expression.Lambda<Func<T, bool>>(methodCall, parameter); | 
|                 } | 
|                 //非string字段,按上面方式处理报异常Null TypeMapping in Sql Tree | 
|                 BinaryExpression body = null; | 
|                 foreach (var value in list) | 
|                 { | 
|                     ConstantExpression constantExpression = Expression.Constant(value); | 
|                     UnaryExpression unaryExpression = Expression.Convert(memberProperty, constantExpression.Type); | 
|   | 
|                     body = body == null | 
|                         ? Expression.Equal(unaryExpression, constantExpression) | 
|                         : Expression.OrElse(body, Expression.Equal(unaryExpression, constantExpression)); | 
|                 } | 
|                 return Expression.Lambda<Func<T, bool>>(body, parameter); | 
|             } | 
|   | 
|             //  object value = propertyValue; | 
|             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)); | 
|             } | 
|   | 
|             UnaryExpression member = Expression.Convert(memberProperty, constant.Type); | 
|             Expression<Func<T, bool>> expression; | 
|             switch (expressionType) | 
|             { | 
|                 //p=>p.propertyName == propertyValue | 
|                 case LinqExpressionType.Equal: | 
|                     expression = Expression.Lambda<Func<T, bool>>(Expression.Equal(member, constant), parameter); | 
|                     break; | 
|                 //p=>p.propertyName != propertyValue | 
|                 case LinqExpressionType.NotEqual: | 
|                     expression = Expression.Lambda<Func<T, bool>>(Expression.NotEqual(member, constant), parameter); | 
|                     break; | 
|                 //   p => p.propertyName > propertyValue | 
|                 case LinqExpressionType.GreaterThan: | 
|                     expression = Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(member, constant), parameter); | 
|                     break; | 
|                 //   p => p.propertyName < propertyValue | 
|                 case LinqExpressionType.LessThan: | 
|                     expression = Expression.Lambda<Func<T, bool>>(Expression.LessThan(member, constant), parameter); | 
|                     break; | 
|                 // p => p.propertyName >= propertyValue | 
|                 case LinqExpressionType.ThanOrEqual: | 
|                     expression = Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter); | 
|                     break; | 
|                 // p => p.propertyName <= propertyValue | 
|                 case LinqExpressionType.LessThanOrEqual: | 
|                     expression = Expression.Lambda<Func<T, bool>>(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<Func<T, bool>>(Expression.Call(member, method, constant), parameter); | 
|                     } | 
|                     else | 
|                     { | 
|                         expression = Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter); | 
|                     } | 
|                     break; | 
|                 default: | 
|                     // p => p.false | 
|                     expression = False<T>(); | 
|                     break; | 
|             } | 
|             return expression; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 创建lambda表达式:p=>false | 
|         /// </summary> | 
|         /// <typeparam name="T"></typeparam> | 
|         /// <returns></returns> | 
|         public static Expression<Func<T, bool>> False<T>() | 
|         { | 
|   | 
|             return p => false; | 
|         } | 
|   | 
|         public static Expression<Func<TEntity, bool>> GetWhereExpression<TEntity>(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<Func<TEntity, bool>> expression = p => false; | 
|             switch (expressionType) | 
|             { | 
|                 //p=>p.propertyName == propertyValue | 
|                 case LinqExpressionType.Equal: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.Equal(member, constant), parameter); | 
|                     break; | 
|                 //p=>p.propertyName != propertyValue | 
|                 case LinqExpressionType.NotEqual: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.NotEqual(member, constant), parameter); | 
|                     break; | 
|                 //   p => p.propertyName > propertyValue | 
|                 case LinqExpressionType.GreaterThan: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.GreaterThan(member, constant), parameter); | 
|                     break; | 
|                 //   p => p.propertyName < propertyValue | 
|                 case LinqExpressionType.LessThan: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.LessThan(member, constant), parameter); | 
|                     break; | 
|                 // p => p.propertyName >= propertyValue | 
|                 case LinqExpressionType.ThanOrEqual: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter); | 
|                     break; | 
|                 // p => p.propertyName <= propertyValue | 
|                 case LinqExpressionType.LessThanOrEqual: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(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<Func<TEntity, bool>>(Expression.Call(member, method, constant), parameter); | 
|                     } | 
|                     else | 
|                     { | 
|                         expression = Expression.Lambda<Func<TEntity, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter); | 
|                     } | 
|                     break; | 
|                 default: | 
|                     //  | 
|                     expression = p => false; | 
|                     break; | 
|             } | 
|             return expression; | 
|         } | 
|     } | 
| } |