2009-03-26 19 views
6

내 도메인에서 POCOS를 사용하고 있으므로 내 저장소에서 내 POCOS 유형의 식 필터를 받고 식의 매개 변수를 내 LINQ 테이블 유형으로 변경하려면 내 필드가 동일해야합니다. 내 구성원으로 이름 그래서 구성원 및 상수로 침입하여 1 및 2 람다 조건에 대해 이것을 수행 할 수 있었다, 만약 내가 더 많은 조건이 이니셜을 반복적으로 구문 분석 리드를 추가합니다. 표현식에서 매개 변수의 유형을 변경하는 방법은 무엇입니까?

내가이

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; 


     } 


    } 

답변

3

아니, 당신이 ParameterExpression의 유형을 변경할 수 없습니다 변경이

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

방법 (달성하는 쉬운 방법이, 내가 종료하는 방법입니다 표현 트리는 불변이다.); 이렇게하려면 전체 트리를 다시 만들어야합니다. 그리고 예, 종종 재발생해야합니다. 죄송합니다 ...

관련 문제