1. 程式人生 > >Util應用程式框架公共操作類(八):Lambda表示式公共操作類(二)

Util應用程式框架公共操作類(八):Lambda表示式公共操作類(二)

using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using DynamicExpression = Util.Lambdas.Dynamics.DynamicExpression; namespace Util { /// <summary> /// Lambda表示式操作 /// </summary> public class Lambda {
#region GetName(獲取成員名稱) /// <summary> /// 獲取成員名稱,範例:t => t.Name,返回 Name /// </summary> /// <param name="expression">表示式,範例:t => t.Name</param> public static string GetName( LambdaExpression expression ) { var memberExpression = GetMemberExpression( expression );
if ( memberExpression == null ) return string.Empty; string result = memberExpression.ToString(); return result.Substring( result.IndexOf( ".", StringComparison.Ordinal ) + 1 ); } /// <summary> /// 獲取成員表示式 /// </summary>
private static MemberExpression GetMemberExpression( LambdaExpression expression ) { if ( expression == null ) return null; var unaryExpression = expression.Body as UnaryExpression; if ( unaryExpression == null ) return expression.Body as MemberExpression; return unaryExpression.Operand as MemberExpression; } #endregion #region GetMember(獲取成員) /// <summary> /// 獲取成員 /// </summary> /// <param name="expression">表示式,範例:t => t.Name</param> public static MemberInfo GetMember( LambdaExpression expression ) { var memberExpression = GetMemberExpression( expression ); if ( memberExpression == null ) return null; return memberExpression.Member; } #endregion #region GetValue(獲取值) /// <summary> /// 獲取值,範例:t => t.Name == "A",返回 A /// </summary> /// <param name="expression">表示式,範例:t => t.Name == "A"</param> public static object GetValue( LambdaExpression expression ) { if ( expression == null ) return null; var memberExpression = expression.Body as MemberExpression; if ( memberExpression != null ) return GetMemberValue( memberExpression ); BinaryExpression binaryExpression = GetBinaryExpression( expression ); if ( binaryExpression != null ) return GetBinaryValue( binaryExpression ); var callExpression = expression.Body as MethodCallExpression; if ( callExpression != null ) return GetMethodValue( callExpression ); return null; } /// <summary> /// 獲取二元表示式 /// </summary> private static BinaryExpression GetBinaryExpression( LambdaExpression expression ) { var binaryExpression = expression.Body as BinaryExpression; if ( binaryExpression != null ) return binaryExpression; var unaryExpression = expression.Body as UnaryExpression; if ( unaryExpression == null ) return null; return unaryExpression.Operand as BinaryExpression; } /// <summary> /// 獲取二元表示式的值 /// </summary> private static object GetBinaryValue( BinaryExpression binaryExpression ) { var unaryExpression = binaryExpression.Right as UnaryExpression; if ( unaryExpression != null ) return GetConstantValue( unaryExpression.Operand ); var memberExpression = binaryExpression.Right as MemberExpression; if ( memberExpression != null ) return GetMemberValue( memberExpression ); return GetConstantValue( binaryExpression.Right ); } /// <summary> /// 獲取屬性表示式的值 /// </summary> private static object GetMemberValue( MemberExpression expression ) { if ( expression == null ) return null; var field = expression.Member as FieldInfo; if ( field != null ) { var constValue = GetConstantValue( expression.Expression ); return field.GetValue( constValue ); } var property = expression.Member as PropertyInfo; if ( property == null ) return null; var value = GetMemberValue( expression.Expression as MemberExpression ); return property.GetValue( value ); } /// <summary> /// 獲取常量值 /// </summary> private static object GetConstantValue( Expression expression ) { var constantExpression = expression as ConstantExpression; if ( constantExpression == null ) return null; return constantExpression.Value; } /// <summary> /// 獲取方法呼叫表示式的值 /// </summary> private static object GetMethodValue( MethodCallExpression callExpression ) { var argumentExpression = callExpression.Arguments.FirstOrDefault(); var memberExpression = argumentExpression as MemberExpression; if ( memberExpression != null ) return GetMemberValue( memberExpression ); return GetConstantValue( argumentExpression ); } #endregion #region GetParameter(獲取引數) /// <summary> /// 獲取引數,範例:t.Name,返回 t /// </summary> /// <param name="expression">表示式,範例:t.Name</param> public static ParameterExpression GetParameter( LambdaExpression expression ) { if ( expression == null ) return null; BinaryExpression binaryExpression = GetBinaryExpression( expression ); if ( binaryExpression == null ) return null; return GetParameterByMember( binaryExpression.Left ); } /// <summary> /// 遞迴獲取引數 /// </summary> private static ParameterExpression GetParameterByMember( Expression expression ) { if ( expression == null ) return null; ParameterExpression result = expression as ParameterExpression; if ( result != null ) return result; MemberExpression memberExpression = expression as MemberExpression; if ( memberExpression == null ) return null; return GetParameterByMember( memberExpression.Expression ); } #endregion #region GetAttribute(獲取特性) /// <summary> /// 獲取特性 /// </summary> /// <typeparam name="TEntity">實體型別</typeparam> /// <typeparam name="TProperty">屬性型別</typeparam> /// <typeparam name="TAttribute">特性型別</typeparam> /// <param name="propertyExpression">屬性表示式</param> public static TAttribute GetAttribute<TEntity, TProperty, TAttribute>( Expression<Func<TEntity, TProperty>> propertyExpression ) where TAttribute : Attribute { var memberInfo = GetMember( propertyExpression ); return memberInfo.GetCustomAttribute<TAttribute>(); } #endregion #region GetAttributes(獲取特性列表) /// <summary> /// 獲取特性列表 /// </summary> /// <typeparam name="TEntity">實體型別</typeparam> /// <typeparam name="TProperty">屬性型別</typeparam> /// <typeparam name="TAttribute">特性型別</typeparam> /// <param name="propertyExpression">屬性表示式</param> public static IEnumerable<TAttribute> GetAttributes<TEntity, TProperty, TAttribute>( Expression<Func<TEntity, TProperty>> propertyExpression ) where TAttribute : Attribute { var memberInfo = GetMember( propertyExpression ); return memberInfo.GetCustomAttributes<TAttribute>(); } #endregion #region Constant(獲取常量) /// <summary> /// 獲取常量表達式,自動轉換值的型別 /// </summary> /// <param name="expression">表示式</param> /// <param name="value"></param> public static ConstantExpression Constant( Expression expression, object value ) { var memberExpression = expression as MemberExpression; if ( memberExpression == null ) return Expression.Constant( value ); return Expression.Constant( value, memberExpression.Type ); } #endregion #region GetCriteriaCount(獲取謂詞條件的個數) /// <summary> /// 獲取謂詞條件的個數 /// </summary> /// <param name="expression">謂詞表達式,範例:t => t.Name == "A"</param> public static int GetCriteriaCount( LambdaExpression expression ) { if ( expression == null ) return 0; var result = expression.ToString().Replace( "AndAlso", "|" ).Replace( "OrElse", "|" ); return result.Split( '|' ).Count(); } #endregion #region Equal(等於表示式) /// <summary> /// 建立等於運算lambda表示式 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> public static Expression<Func<T, bool>> Equal<T>( string propertyName, object value ) { var parameter = CreateParameter<T>(); return parameter.Property( propertyName ) .Equal( value ) .ToLambda<Func<T, bool>>( parameter ); } /// <summary> /// 建立引數 /// </summary> private static ParameterExpression CreateParameter<T>() { return Expression.Parameter( typeof( T ), "t" ); } #endregion #region NotEqual(不等於表示式) /// <summary> /// 建立不等於運算lambda表示式 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> public static Expression<Func<T, bool>> NotEqual<T>( string propertyName, object value ) { var parameter = CreateParameter<T>(); return parameter.Property( propertyName ) .NotEqual( value ) .ToLambda<Func<T, bool>>( parameter ); } #endregion #region Greater(大於表示式) /// <summary> /// 建立大於運算lambda表示式 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> public static Expression<Func<T, bool>> Greater<T>( string propertyName, object value ) { var parameter = CreateParameter<T>(); return parameter.Property( propertyName ) .Greater( value ) .ToLambda<Func<T, bool>>( parameter ); } #endregion #region Less(小於表示式) /// <summary> /// 建立小於運算lambda表示式 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> public static Expression<Func<T, bool>> Less<T>( string propertyName, object value ) { var parameter = CreateParameter<T>(); return parameter.Property( propertyName ) .Less( value ) .ToLambda<Func<T, bool>>( parameter ); } #endregion #region GreaterEqual(大於等於表示式) /// <summary> /// 建立大於等於運算lambda表示式 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> public static Expression<Func<T, bool>> GreaterEqual<T>( string propertyName, object value ) { var parameter = CreateParameter<T>(); return parameter.Property( propertyName ) .GreaterEqual( value ) .ToLambda<Func<T, bool>>( parameter ); } #endregion #region LessEqual(小於等於表示式) /// <summary> /// 建立小於等於運算lambda表示式 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> public static Expression<Func<T, bool>> LessEqual<T>( string propertyName, object value ) { var parameter = CreateParameter<T>(); return parameter.Property( propertyName ) .LessEqual( value ) .ToLambda<Func<T, bool>>( parameter ); } #endregion #region Contains(呼叫Contains方法) /// <summary> /// 呼叫Contains方法 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> public static Expression<Func<T, bool>> Contains<T>( string propertyName, object value ) { return Call<T>( propertyName, "Contains", value ); } /// <summary> /// 呼叫方法 /// </summary> private static Expression<Func<T, bool>> Call<T>( string propertyName, string methodName, object value ) { var parameter = CreateParameter<T>(); return parameter.Property( propertyName ) .Call( methodName, value ) .ToLambda<Func<T, bool>>( parameter ); } #endregion #region Starts(呼叫StartsWith方法) /// <summary> /// 呼叫StartsWith方法 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> public static Expression<Func<T, bool>> Starts<T>( string propertyName, string value ) { var parameter = CreateParameter<T>(); var property = parameter.Property( propertyName ); var call = Expression.Call( property, property.Type.GetMethod( "StartsWith", new Type[] { typeof( string ) } ), Expression.Constant( value ) ); return call.ToLambda<Func<T, bool>>( parameter ); } #endregion #region Ends(呼叫EndsWith方法) /// <summary> /// 呼叫EndsWith方法 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> public static Expression<Func<T, bool>> Ends<T>( string propertyName, string value ) { var parameter = CreateParameter<T>(); var property = parameter.Property( propertyName ); var call = Expression.Call( property, property.Type.GetMethod( "EndsWith", new Type[] { typeof( string ) } ), Expression.Constant( value ) ); return call.ToLambda<Func<T, bool>>( parameter ); } #endregion #region ParsePredicate(解析為謂詞表達式) /// <summary> /// 解析為謂詞表達式 /// </summary> /// <typeparam name="T">實體型別</typeparam> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> /// <param name="operator">運算子</param> public static Expression<Func<T, bool>> ParsePredicate<T>( string propertyName, object value, Operator @operator ) { var parameter = Expression.Parameter( typeof( T ), "t" ); return parameter.Property( propertyName ).Operation( @operator, value ).ToLambda<Func<T, bool>>( parameter ); } /// <summary> /// 解析為謂詞表達式 /// </summary> /// <typeparam name="T">實體型別</typeparam> /// <param name="predicateExpression">謂詞表達式字串,引數佔位符為@0,@1,@2 ...</param> /// <param name="values"></param> public static Expression<Func<T, bool>> ParsePredicate<T>( string predicateExpression, params object[] values ) { return DynamicExpression.ParseLambda( typeof( T ), typeof( bool ), predicateExpression, values ) as Expression<Func<T, bool>>; } #endregion } }