2012-03-10 56 views
0

我有viewmodel(比如memberviewmodel)和ef模型(比如member)。我要如何轉置或轉換表達式Linq

> GetByProperty(Expression<Func<MemberViewModel, bool>> whereCondition) 

轉化爲

> GetByProperty(Expression<Func<Member, bool>> whereCondition) 

什麼想法?

我的服務公開方法GetByProperty(Expression> whereCondition),但在服務內部,它調用公開方法GetByProperty(Expression> whereCondition)的業務對象。

+0

你是什麼意思翻譯?你想打電話給梅格爾嗎? – 2012-03-10 08:00:59

+0

我該如何溝通這兩種方法?你不能使用whereCondition將它傳遞給第二種方法,對嗎? – user384080 2012-03-10 08:19:03

回答

1

要將Expression<Func<MemberViewModel, bool>>轉換爲Expression<Func<Member, bool>>,您需要擴展ExpressionVisitor類。我假設MemberViewModel只包含字段和屬性。 Member當然需要實現相同的一組字段和屬性。在這種情況下,下面應該工作:

public class ParameterModifier<TSrc, TDest> : ExpressionVisitor 
{ 
    ParameterExpression parameter; 

    public ParameterModifier() 
    { 
     parameter = Expression.Parameter(typeof(TDest), "member"); 
    } 

    protected override Expression VisitParameter(ParameterExpression node) 
    { 
     if (node.Type == typeof(TSrc)) 
     { 
      return parameter; 
     } 
     else 
      return base.VisitParameter(node); 
    } 

    protected override Expression VisitMember(MemberExpression node) 
    { 
     if (node.Expression.Type == typeof(TSrc)) 
     { 
      return Expression.PropertyOrField(Visit(node.Expression), node.Member.Name); 
     } 
     else 
     { 
      return base.VisitMember(node); 
     } 
    } 

    protected override Expression VisitLambda<T>(Expression<T> node) 
    { 
     if (node.Parameters.Any(p => p.Type == typeof(TSrc))) 
     { 
      return Expression.Lambda(Visit(node.Body), node.Parameters.Select(p => p.Type == typeof(TSrc) ? parameter : p)); 
     } 
     else 
     { 
      return base.VisitLambda<T>(node); 
     } 
    } 
} 

傳遞謂詞使用上述類的第二種方法,你現在可以把它轉換前:

IEnumerable<MemberViewModel> GetByProperty(Expression<Func<MemberViewModel, bool>> whereCondition) 
{ 
    var converter = new ParameterModifier<MemberViewModel, Member>(); 
    var convertedExpression = converter.Visit(original) as Expression<Func<Member, bool>>; 
    IEnumerable<Member> members = GetByProperty(convertedExpression); 
    return members.Select(new MemberViewModel(member)); 
}