2012-10-11 78 views
1

我目前有LAMBDA Expresion:http://pastebin.com/ZGCiQdHe查詢三重選擇

,我得到的ArgumentException在53線 http://msdn.microsoft.com/en-us/library/bb340145(v=vs.90).aspx

var lExpresion = Expression.Lambda<Func<TEntity, bool>>(body, parametrsNumber, parametrsTyp, parametrsLp); 

,可是我不明白我做錯了。

我想:

WHERE ((twr_gidnumer =1 and twr_gidtyp = 1 and twr_gidlp = 1) OR 
    (twr_gidnumer =1 and twr_gidtyp = 1 and twr_gidlp = 2)) 

--ANSWERR FULL

基於文章:

http://blogs.msdn.com/b/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx https://stackoverflow.com/Converting 2 argument Lambda expression to 1 argument Lambda expression

public static Expression<Func<CDNXL_TwrKarty, bool>> Bind2nd(Expression<Func<CDNXL_TwrKarty, CDNXL_TwrKarty,CDNXL_TwrKarty, bool>> source) 
{ 
    Expression newBody = new Rewriter(source.Parameters[0]).Visit(source.Body); 
    return Expression.Lambda<Func<CDNXL_TwrKarty, bool>>(newBody, source.Parameters[0]); 
} 

internal class Rewriter : ExpressionVisitor 
{ 
    private readonly ParameterExpression candidate_; 

    public Rewriter(ParameterExpression candidate) 
    { 
     candidate_ = candidate; 
    } 

    protected override Expression VisitParameter(ParameterExpression p) 
    { 
     return candidate_; 
    } 
} 
//REPLACE EXECUTING PLACE 
var retMultiLamnda = Expression.Lambda<Func<CDNXL_TwrKarty, CDNXL_TwrKarty, CDNXL_TwrKarty, bool>>(body, parametrsNumber, parametrsTyp, parametrsLp); 
var retOneLambda = Bind2nd(retMultiLamnda); 
var retQuery = query.Where(retOneLambda); 
return retQuery; 

Thanx Rafal尋求幫助。

+0

+1爲ExprssionVisitor很高興有 – Rafal

回答

1

我看到的第一件事是您的委託類型不會與您的調用列表進行數學運算。您期望創建一個函數,該函數接收一個類型爲TEntity的參數,但您傳遞樹參數表達式來運行。請注意,您執行此Lablda method的超載。

OK,我會試着更清楚:

Expression.Lambda<Func<Arg1Type,...,ArgNType,ReturnType>> 
    (body,parameterExpressionForArg1,...,parameterExpressionForArgN); 

這些通用參數ArgType必須parameterExpressionsForArg匹配。對於參數,必須有相同數量的泛型類型作爲parameterExpressions。這些類型也必須匹配。

所以,如果你想有樹parameterExpressions出於某種原因,那麼你必須有樹的論點在你的方法:

Expression.Lambda<Func<CDNXL_TwrKarty,CDNXL_TwrKarty,CDNXL_TwrKarty, bool>>(body, parametrsNumber, parametrsTyp, parametrsLp); 

可能是在這種情況下正確的調用顯然它不會匹配Where電話。

如果要將樹表達式合併爲一個匹配的Where參數,則必須替換所有冗餘ParamteterExpressions

+0

我刪除TEntity並寫一個類http://pastebin.com/92PetJLK。結果相同。 –

+0

但是,如何減少到一個參數? –

+0

您需要遍歷這些表達式樹並創建自己的表達式。研究[這個問題](http://stackoverflow.com/questions/11573517/generic-method-to-calcuate-euclidean-distance-using-expressions/11574571#11574571)這個話題是由我和銥星覆蓋。這個任務的複雜性將取決於傳遞給你函數的表達式。 – Rafal