How to change the type of a parameter in an expression?

since I use POCOS in my domain, I want my repository to be able to receive Expression filters like my POCOS and change the parameter in the expression as the type of my LINQ tables, my fields have the same name as my members, so I was able to do this for lambda conditions 1 and 2, dividing into terms and constants, if I add additional conditions, this will lead to a recursive analysis of the binary expression.

this is how i ended up is there an easy way to do this

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

way to change it

 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; } } 
+6
lambda linq expression-trees
source share
1 answer

No, you cannot change the type of ParameterExpression (expression trees are immutable); You will need to rebuild the entire tree to do this. And yes, you often have to rewrite it. Unfortunately...

+3
source share

All Articles