首页 新闻 会员 周边 捐助

ExpressionTree描述属性与属性之间的逻辑关系。

0
悬赏园豆:10 [待解决问题]

我正在写一个Expression引擎。传入一个对象,然后将对象的属性转化为一个Expression<Func<T,bool>>。

在下文中传入对象用Parameter替代。

我打算采用在 Parameter的属性上加Attribute的方法,来定义单个属性与该属性值之间的算术运算关系(==、>=、<=等)。
然而,我不知道采用什么方法,能够正确简洁的描述属性与属性之间的逻辑运算关系(&&、||)。
不知有人可否有思路?

Sago的主页 Sago | 初学一级 | 园豆:48
提问于:2015-11-22 12:21
< >
分享
所有回答(2)
0

将参数包装成表达式,然后Expression.And/Or

jello chen | 园豆:7336 (大侠五级) | 2015-11-22 13:22
0

类1:

 public class ParameterReset : ExpressionVisitor
    {
        private Dictionary<ParameterExpression, ParameterExpression> Dictionary { get; set; }

        public ParameterReset(Dictionary<ParameterExpression, ParameterExpression> dictionary)
        {
            this.Dictionary = dictionary ?? new Dictionary<ParameterExpression, ParameterExpression>();
        }

        public static Expression ReplaceParameterList(Dictionary<ParameterExpression, ParameterExpression> dictionary, Expression expression)
        {
            return new ParameterReset(dictionary).Visit(expression);
        }

        protected override Expression VisitParameter(ParameterExpression param)
        {
            ParameterExpression replaceParam;
            if (Dictionary.TryGetValue(param, out replaceParam))
            {
                param = replaceParam;
            }
            return base.VisitParameter(param);
        }
    }

添加类2

public static class ExpressionExtend
    {
        public static object Eval(this Expression expr)
        {
            return expr.Eval<object>();
        }

        public static T Eval<T>(this Expression expr)
        {
            var constantExpr = expr as ConstantExpression;
            if (constantExpr != null)
            {
                return (T)constantExpr.Value;
            }
            var fun = Expression.Lambda<Func<object>>(Expression.Convert(expr, typeof(object))).Compile();

            return (T)(fun());
        }


        //整合两个表达式
        public static Expression<T> Splice<T>(this Expression<T> left, Expression<T> right, Func<Expression, Expression, Expression> method)
        {
            var dictionary = left.Parameters.Select((f, i) => new { f, s = right.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
            //替换参数
            var secondBody = ParameterReset.ReplaceParameterList(dictionary, right.Body);
            return Expression.Lambda<T>(method(left.Body, secondBody), left.Parameters);
        }
    }

使用的时候

表达式1.Splice(表达式2, Expression.OrElse);

表达式1.Splice(表达式2, Expression.AndAlso);

把这个用运算符重载就可以达到了。like this

 public static QueryCondition<T> operator &(QueryCondition<T> condition, Expression<Func<T, bool>> right)
        {
            if (condition != null && condition.Where != null)
            {
                condition.Where = condition.Where.Splice(right, Expression.AndAlso);
            }
            else
            {
                condition.Where = right;
            }
            return condition;
        }
        public static QueryCondition<T> operator |(QueryCondition<T> condition, Expression<Func<T, bool>> right)
        {
            if (condition != null && condition.Where != null)
            {
                condition.Where = condition.Where.Splice(right, Expression.OrElse);
            }
            else
            {
                condition.Where = right;
            }
            return condition;
        }
古月三石 | 园豆:259 (菜鸟二级) | 2015-11-24 15:39

先谢谢您的答复,我先领域一下您的想法。

支持(0) 反对(0) Sago | 园豆:48 (初学一级) | 2015-11-25 21:15
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册