Как изменить тип параметра в выражении? - PullRequest
6 голосов
/ 26 марта 2009

, так как я использую POCOS в своем домене, я хочу, чтобы мой репозиторий мог получать фильтры Expression типа моего POCOS и изменять параметр в выражении, чтобы он соответствовал типу моих таблиц LINQ, мои поля имеют То же имя, что и у моих членов, поэтому я смог выполнить это для 1 и 2 лямбда-условий, разбив элементы и константы, если я добавлю больше условий, это приведет к рекурсивному анализу двоичного выражения.

Вот как я закончил, есть ли простой способ сделать это

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;


        }


    }

1 Ответ

3 голосов
/ 31 марта 2009

Нет, вы не можете изменить тип ParameterExpression (деревья выражений неизменны); вам придется перестроить все дерево, чтобы сделать это. И да, вам часто приходится повторять это. К сожалению ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...