.net - 如何更改表达式中参数的类型?

标签 .net linq c#-3.0 lambda expression-trees

由于我在域中使用 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;


        }


    }

最佳答案

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

关于.net - 如何更改表达式中参数的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/684767/

相关文章:

c# - Linq 是否消除了对 Hibernate 的需求?

javascript - MS Bot Framework 将值从服务器代码 (C#) 传递到前端代码 (JavaScript)

c# - 从列表中获取相同元素的总和

c# - 为 .NET 使用定义此 native 接口(interface)的最佳方法是什么?

c# - 如何处理 EF Core 上的并发

c# - Entity Framework 按月分组

c# - 在 C# 3.0 中我们使用 "var"在 C# 2.0 中它的替代品是什么?

c# - 验证对象在 Rhino Mocks 中调用自身

c# - 事件和线程

c# - 不带组的对象的 Linq 总和