2014-12-04 3 views
2

두 개의 표현식이 있습니다. 표현식을 변환하는 올바른 방법 <Func <Foo, bool>> 다른 표현식 <Func <Bar, bool>>

나는 유형의 조건 입력이 Expression<Func<Foo, bool>>

내가이 일에 대해 갈 수있는 논리가 될 것입니다 무엇

유형 Expression<Func<Bar, bool>>에 소스 식을 변환 하시겠습니까? 나는 Expression.Convert()을 사용하려고했지만 잘못하고 있다고 생각합니다.

+1

'Bar'가'Foo'를 상속합니까? – haim770

+2

'Bar'와'Foo'의 관계는 무엇입니까? –

+0

아니요, '바'와 '파'는 밀접한 관련이 있습니다. 필자의 경우, 하나는 L2S 생성 클래스이고 다른 하나는 내 자신의 Data 클래스입니다. 많은 속성이 비슷하거나 같습니다. 따라서 어떻게 든 변환에 매핑해야합니다. 그건 내가 누락 된 것/도움이 필요한 부분이다. 나는 일반적인 레포 메소드'Find (Expression > 술어)'를 가지고 있는데, 여기서 T는 나의 데이터 타입이다. 하지만 L2S 컨텍스트에서 Where 식에서 사용할 수 있도록 T를 L2S 형식으로 변환해야합니다. –

답변

3

Expression<Func<Foo, bool>>Expression<Func<Bar, bool>>으로 변환하려면 변환을 처리하기 위해 Expression<Func<Bar, Foo>>이 필요합니다.

당신이하고있는 일은 간단히 표현식을 작성하는 것입니다. 표현식 작성은 함수를 작성하는 것보다 약간 더 복잡합니다. 여기서 표현식 작성은 단순히 결과를 매개 변수로 전달하여 호출 할 수 있습니다. 이것은 다음과 같은 방법에 의존

public static Expression<Func<TFirstParam, TResult>> 
    Compose<TFirstParam, TIntermediate, TResult>(
    this Expression<Func<TFirstParam, TIntermediate>> first, 
    Expression<Func<TIntermediate, TResult>> second) 
{ 
    var param = Expression.Parameter(typeof(TFirstParam), "param"); 

    var newFirst = first.Body.Replace(first.Parameters[0], param); 
    var newSecond = second.Body.Replace(second.Parameters[0], newFirst); 

    return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param); 
} 

다른 하나 개의 표현의 모든 인스턴스를 대체 할 :

public static Expression Replace(this Expression expression, 
    Expression searchEx, Expression replaceEx) 
{ 
    return new ReplaceVisitor(searchEx, replaceEx).Visit(expression); 
} 
internal class ReplaceVisitor : ExpressionVisitor 
{ 
    private readonly Expression from, to; 
    public ReplaceVisitor(Expression from, Expression to) 
    { 
     this.from = from; 
     this.to = to; 
    } 
    public override Expression Visit(Expression node) 
    { 
     return node == from ? to : base.Visit(node); 
    } 
} 
여기에서 우리는 첫 번째의 몸에 두 번째 함수의 매개 변수의 모든 인스턴스를 교체해야

이제 우리는 다음을 할 수 있습니다 :

Expression<Func<Foo, bool>> predicate = GetPrediate(); 
Expression<Func<Bar, Foo>> selector = GetSelector(); 
Expression<Func<Bar, bool>> newPredicate = selector.Compose(predicate); 
+0

'GetSelector()'는 어디에 정의되어 있습니까? 내 가정은'GetPredicate()'이 내가 전달한 나의 원래 표현이 될 것입니다. 나는 당신의 예제에 혼란스러워합니다. –

+0

@IssaFram "Expression 을'Expression > '로 변환하기 위해서는'Expression >'도 필요합니다. 전환을 처리 할 수 ​​있습니다. " 어딘가에서 가져야하거나 다른 곳에서 만들어야합니다. 이러한 유형에 대해 알지 못하는 한 표현식을 만들어 다른 표현식으로 변환하는 방법에 대해 설명 할 수는 없습니다. – Servy

+0

그건 의미가 있습니다. 나는 처음에는 혼란 스러웠다. 그 표현을 아무 문제없이 만들 수 있습니다. 도움에 감사드립니다. –