Util應用程式框架公共操作類(八):Lambda表示式公共操作類(二)
阿新 • • 發佈:2018-12-29
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
}
}