¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |