博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

解析Expression

Posted on 2020-05-09 10:28  筑筑  阅读(842)  评论(0编辑  收藏  举报
 private static void GetExpression<T2>(Expression expression)
        {

            if (expression.NodeType != ExpressionType.Constant)
            {
                var _expression = expression as BinaryExpression;
                if (_expression == null || expression.NodeType == ExpressionType.Lambda)
                {
                    _expression = GetBinaryExpression(expression);
                }

                if (AnyBinaryOperator(_expression.NodeType))
                {
                    var _leftExpression = _expression.Left;
                    GetExpression<T2>(_leftExpression);
                    var _rightExpression = _expression.Right;
                    GetExpression<T2>(_rightExpression);
                }
                else
                {
                    Results.Add(GetExpressionResult<T2>(_expression));
                }
            }
        }
/// <summary>
        /// escape to the lambda
        /// </summary>
        private static BinaryExpression GetBinaryExpression(Expression expression)
        {
            
            LambdaExpression lambda = expression as LambdaExpression;
         
            var lambdaExpression = lambda.Body;

            return lambdaExpression as BinaryExpression;
            
        }
/// <summary>
        /// get result
        /// </summary>
        private static ExpressionResult GetExpressionResult<T2>(BinaryExpression expression)
        {
            var left_Name = GetLeftExpression<T2>(expression);

            var right_Name = GetRightExpression(expression);

            return new ExpressionLambdaResult()
            {
                expressionType = expression.NodeType,
                propertyName = left_Name,
                propertyValue = right_Name
            };

        }
 /// <summary>
        /// get dto attribute 
        /// </summary>
        private static string GetLeftExpression<T2>(BinaryExpression expression)
        {
            var leftExpression = expression.Left as MemberExpression;

            var ps = typeof(T2).GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            var first = ps.Where(x => x.GetCustomAttribute<EntityDataNameAttribute>(true) != null && x.Name.ToLower() == leftExpression.Member.Name.ToLower()).FirstOrDefault();

            return first != null ? first.GetCustomAttribute<EntityDataNameAttribute>(true).EntityDataName : leftExpression.Member.Name;
        }
/// <summary>
        /// get constant value
        /// </summary>
        private static object GetRightExpression(BinaryExpression expression)
        {
            var rootExpression = expression.Right as MemberExpression;
            var constExpr = rootExpression.Expression as ConstantExpression;

            if (constExpr == null)
            {
                object value = Expression.Lambda(expression.Right).Compile().DynamicInvoke();
                if (value == null) return value = string.Empty;
                if (getPropertyType(value.GetType()) == typeof(Nullable))
                {
                    var ps = value.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
                    var first = ps.Where(x => x.GetCustomAttribute<EntityDataNameAttribute>(true) != null).FirstOrDefault();
                    if (first == null)
                    {
                        throw new Exception(" Attribute is empty ");
                    }
                    value = value.GetType().GetProperty(first.Name).GetValue(value, null);
                }
                else if (getPropertyType(value.GetType()) == typeof(ListClass))
                {

                }
                return value;
            }
            else
            {
                var memberInfos = new Stack<MemberInfo>();

                memberInfos.Push(rootExpression.Member);

                object objReference = constExpr.Value;

                var mi = memberInfos.Pop();

                var objField = objReference.GetType().GetField(mi.Name);

                return objField.GetValue(objReference);
            }
        }
/// <summary>
        /// any  binary operator
        /// </summary>
        /// <param name="expressiontype"></param>
        /// <returns></returns>
        private static bool AnyBinaryOperator(ExpressionType expressiontype)
        {
            bool Any = true;
            switch (expressiontype)
            {
                case ExpressionType.AndAlso: break;
                case ExpressionType.And: break;
                case ExpressionType.OrElse: break;
                case ExpressionType.Or:break;
                default:
                    Any = !Any;
                    break;
            }
            return Any;
        }
public class ExpressionLambdaResult: ExpressionResult
    {
        public string propertyName { get; set; }
        public object propertyValue { get; set; }
    }
    public class ExpressionResult
    {
        public ExpressionType expressionType { get; set; }
    }