2012-11-26 3 views
1

에서 표현식 만들기 :C#을 식 - 나는 이런 식으로 뭔가 보이는 표현을 사용하여 재사용 가능한 방법을 만들기 위해 노력하고 또 다른 표현

Expression<Func<Order, bool>> CreateExpression(Expression<Func<Order, int>> parameter, FilterOperator operator, int value) 

그래서 나는이 같이 사용할 수 있습니다 :

IQueryable<Order> orders = db.Orders; 

var filtered = orders.Where(CreateExpression(o => o.OrderID, FilterOperator.GreaterThan, 100)); 

방법을 쓰는 방법을 잘 모르겠습니다. 이 표현식을 생성하는 메소드를 작성하려면 어떻게해야합니까?

if(operator == FilterOperator.GreaterThan) 
    return m => m.OrderID > value; 
else if(operator == FilterOperator.LessThan) 
    return m => m.OrderID < value; 

하지만 직접 OrderID를 사용하는 대신에 전달되는 표현을 사용하려면 :

나는 같은 것을 할 수 있어야합니다. 어떻게해야합니까?

+1

그것보다 쉽게하지 않을까요 단지 '명령. 어디에서 (o => o. 오더 ID> 100)'? 그게 왜 효과가 없다는 것을 알았 더라면, 나는 더 나은 제안을 할 수있었습니다. –

+0

같은 논리를 OrderID, OrderQuantity 등에 적용하고 GreaterThan, LessThan, GreaterThanEqualTo, EqualTo, NotEqualTo 등을 적용하기를 원하므로이 작업을 수행하고 싶지 않습니다. – Dismissile

+1

그러나 람다는 간단하게 당신이 원하는 조건으로 새로운 것. –

답변

5
static Expression<Func<T, bool>> CreateExpression<T>(Expression<Func<T, int>> parameter, FilterOperator @operator, int value) 
{ 
    var argExpr = Expression.Parameter(typeof(T), "p"); 
    var paramExpr = Expression.Invoke(parameter, argExpr); 
    var constExpr = Expression.Constant(value); 
    Expression compExpr = null; 
    switch(@operator) 
    { 
     case FilterOperator.GreaterThan: 
      compExpr = Expression.GreaterThan(paramExpr, constExpr); 
      break; 
     case FilterOperator.LessThan: 
      compExpr = Expression.LessThan(paramExpr, constExpr); 
      break; 
    } 

    return Expression.Lambda<Func<T, bool>>(compExpr, argExpr); 
} 

Invoke을 사용할 수 없습니다 당신의 parameter 표현 멤버 표현 인 경우에, 당신은 당신의 새 매개 변수를 사용하여 다시 만들 수 있습니다

static Expression<Func<T, bool>> CreateExpression<T>(Expression<Func<T, int>> parameter, FilterOperator @operator, int value) 
{ 
    var memberExpr = (MemberExpression)parameter.Body; 
    PropertyInfo property = (PropertyInfo)memberExpr.Member; 

    var argExpr = Expression.Parameter(typeof(T), "p"); 
    var propertyExpr = Expression.Property(argExpr, property); 
    var constExpr = Expression.Constant(value); 

    Expression compExpr = null; 
    switch(@operator) 
    { 
     case FilterOperator.GreaterThan: 
      compExpr = Expression.GreaterThan(propertyExpr, constExpr); 
      break; 
     case FilterOperator.LessThan: 
      compExpr = Expression.LessThan(propertyExpr, constExpr); 
      break; 
    } 

    return Expression.Lambda<Func<T, bool>>(compExpr, argExpr); 
} 
+0

IQueryable과 Invoke가 지원되지 않는다는 오류가 나타납니다. 이것에 대한 대안이 있습니까? – Dismissile

+0

@Dismissile -'parameter' 표현식이 속성 접근자인 경우 yes입니다. 내가 잠시 후에 다시 ... – Lee

+0

예 그것은 POCO에있는 속성입니다. – Dismissile