using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; using WIDESEAWCS_Core.Enums; using WIDESEAWCS_Core.Helper; namespace WIDESEAWCS_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; } } }