6

ドメインでPOCOSを使用しているため、リポジトリで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;


        }


    }
4

1 に答える 1

3

いいえ、a の型を変更することはできませんParameterExpression(式ツリーは不変です)。これを行うには、ツリー全体を再構築する必要があります。そして、はい、しばしばそれを再帰する必要があります。ごめん...

于 2009-03-31T04:18:27.707 に答える