2009-03-26 12 views
6

dado que estoy usando POCOS en mi dominio, quiero que mi repositorio pueda recibir filtros de expresiones del tipo de mis POCOS y cambie el parámetro en la expresión para que sea del tipo de mis tablas LINQ, mis campos tienen el mismo nombre como mis miembros, así que pude lograr esto para 1 y 2 condiciones lambda mediante la división en miembros y constantes, si agrego más condiciones, esto lleva a analizar de manera recursiva la expresión binaria.cómo cambiar el tipo de parámetro en una expresión?

Éste es cómo terminó, ¿hay una manera fácil de lograr esto

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

el camino lo cambio

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; 


     } 


    } 

Respuesta

3

No, no se puede cambiar el tipo de un ParameterExpression (los árboles de expresión son inmutables); tendrías que reconstruir todo el árbol para hacer esto. Y sí, a menudo tienes que repetirlo. Lo siento ...

Cuestiones relacionadas