2016-03-28 20 views
0

我試圖建立必須創建類型的查詢凡() 對於IN如果值列表中存在我必須檢查的表達,所以我的表達是這樣的:極力打造拉姆達樹

long loKey = 2; 
List<long> loKeys = new List<long>(); 
loKeys.Add(loKey); 

ParameterExpression parameter = Expression.Parameter(type, "t"); 
var constantExpression = Expression.Constant((List<long>)loKeys, typeof(List<long>)); 
var lambda = Expression.Lambda(
    typeof(Func<,>).MakeGenericType(type, typeof(bool)), 
    Expression.Equal(
     Expression.Property(parameter, "ID"), 
     constantExpression 
    ), 
    parameter 
); 
resultQuery = resultQuery.Provider.CreateQuery(
    Expression.Call(
     typeof(Queryable), 
     "Where", 
     new Type[] { type }, 
     resultQuery.Expression, 
     lambda 
    ) 
); 

這樣的想法是,field ID必須存在於名單loKeys,但我得到一個錯誤:

Additional information: The binary operator Equal is not defined for the types 'System.Int64' and 'System.Collections.Generic.List`1[System.Int64]'.

在Expression.Lambda - > MakeGenericType

+0

何不'使用類似'query.Where(entity => keysEnumerable.Contains(entity.Id))'',其中'keysEnumerable'是'IEnumerable '? – Dennis

+0

因爲我的查詢沒有類型,所以我不能使用.Where –

回答

3

所以,你正在試圖建立這樣的事情:

t => loKeys.Contains(t.ID) 

你需要考慮的唯一的事情是實際ContainsEnumerable類中定義的靜態擴展方法:

var lambda = Expression.Lambda(
    Expression.Call(
     typeof(Enumerable), 
     "Contains", 
     new[] { typeof(long) }, 
     Expression.Constant(loKeys), 
     Expression.Property(parameter, "ID") 
    ), 
    parameter 
); 
1

我認爲它是由於該部分引發的異常: Expression.Equal( Expression.Property(parameter,「ID」), constantExpression ), 其中比較了常量列表constantExpressions,它是一個通用列表,參數類型爲long(我猜,沒有說明參數是什麼類型),也許而不是等於您應該使用Method調用「Contains」並查看參數是否在列表中(如Dennis建議的)。

+0

是的,是的,我關於同樣的事情,但表達式沒有方法包含..所以真正的問題是什麼方法可以用來代替平等嗎? –

+0

@HarryBirimirski如果'type'總是'ICollection',則可以使用Expression.Call並將'ICollection.Contains()'作爲methodInfo傳遞給它 –