6

因为我在我的域中使用 POCOS,我希望我的存储库能够接收我的 POCOS 类型的表达式过滤器并将表达式中的参数更改为我的 LINQ 表的类型,我的字段具有相同的名称我的成员,所以我能够通过分解成员和常量来完成 1 和 2 lambda 条件,如果我添加更多条件,这将导致递归解析二进制表达式。

我就是这样结束的,有没有简单的方法来完成这个

var q = from p in 
        db.products.Where(ExpressionBuilder.Create<MyPocoProduct,LinqProduct>(myPocoProductExpression))

我改变它的方式

public class ExpressionBuilder
    {
        public static Expression<Func<TLinq, bool>> Create<TEntity, TLinq>(Expression<Func<TEntity, bool>> predicate)
        {

            try
            {
                //get the predicate body
                var binaryExpr = (BinaryExpression)predicate.Body;

                //holds the resuting Expression
                var expressionResult = default(BinaryExpression);

                // Create the parameter of the Linq table Type 
                ParameterExpression parameter = Expression.Parameter(typeof(TLinq), predicate.Parameters[0].Name);


                //if only one condition was passed
                if (binaryExpr.Left is MemberExpression)
                {
                    expressionResult = CreateExpression(binaryExpr, parameter,binaryExpr.NodeType);

                }
                else if (binaryExpr.Left is BinaryExpression)
                {
                    var predicatesList = new List<BinaryExpression>();

                    var leftExp = CreateExpression((BinaryExpression)binaryExpr.Left, parameter, binaryExpr.Left.NodeType);
                    var RightExp = CreateExpression((BinaryExpression)binaryExpr.Right, parameter, binaryExpr.Right.NodeType);

                   expressionResult = Expression.And(leftExp, RightExp);


                }

                return Expression.Lambda<Func<TLinq, bool>>(expressionResult, parameter);
            }
            catch (Exception ex)
            {
                throw new Exception("Eror While creating Filter", ex);
            }

        }

        private static BinaryExpression CreateExpression(BinaryExpression expression, ParameterExpression parameter,ExpressionType expType)
        {

            var memberExp = expression.Left as MemberExpression;

            if (memberExp == null) throw new ArgumentException("left  expression is not a member Expression");

            //create the Member expression
            MemberExpression member = LambdaExpression.PropertyOrField(parameter, memberExp.Member.Name);

            //create the constant against the value
            ConstantExpression constant = Expression.Constant(((ConstantExpression)expression.Right).Value);


            return CreateExpressionOfType(expType, member, constant);


        }


        private static BinaryExpression CreateExpressionOfType(ExpressionType expType, MemberExpression member, ConstantExpression constant)
        {

            //creates the body fo the lambda 
            var resultExpression = default(BinaryExpression);
            switch (expType)
            {

                case ExpressionType.And:
                    break;
                case ExpressionType.AndAlso:
                    break;
                case ExpressionType.ConvertChecked:
                    break;
                case ExpressionType.Equal:
                    resultExpression = Expression.Equal(member, constant);
                    break;
                case ExpressionType.ExclusiveOr:
                    break;
                case ExpressionType.GreaterThan:
                    resultExpression = Expression.GreaterThan(member, constant);
                    break;
                case ExpressionType.GreaterThanOrEqual:
                    break;
                case ExpressionType.LessThan:
                    resultExpression = Expression.LessThan(member, constant);
                    break;
                case ExpressionType.LessThanOrEqual:
                    break;
                case ExpressionType.Not:
                    break;
                case ExpressionType.NotEqual:
                    break;
                default:
                    break;
            }

            return resultExpression;


        }


    }
4

1 回答 1

3

不,您不能更改 a 的类型ParameterExpression(表达式树是不可变的);你必须重建整个树才能做到这一点。是的,你经常不得不递归它。对不起...

于 2009-03-31T04:18:27.707 回答