2017-10-07 6 views
0

にList.Contains変換:に関連する表現ツリー

私は Expression Treeバージョンを書きたい、このクエリに直面して、私の前の質問の以下では

Create a Lambda Expression With 3 conditions

Convert Contains To Expression Tree

List<byte?> lst = new List<byte?>{1,2}; 
from a in myTbl 
where a.Age = 20 && lst.Contains(a.Status) 
select a 

私はこのコードを書きます

List<byte?> lst = new List<byte?>{1,2}; 
var param = Expression.Parameter(typeof(T), "o"); 
var body = Expression.AndAlso(
       Expression.Equal(
        Expression.PropertyOrField(param, "Age"), 
        Expression.Constant(20) 
       ), 
       Expression.Call(Expression.PropertyOrField(param, "Status"), 
            "Contains", 
            Type.EmptyTypes, 
            Expression.Constant(lst))); 

var lambda = Expression.Lambda<Func<T, bool>>(body, param); 
return lambda; 

と私はエラーを取得する:

"No method 'Contains' exists on type 'System.Nullable`1[System.Byte]'."

は、問題を見つけるために私を助けてください。それができる

public static bool Contains<TSource>(
    this IEnumerable<TSource> source, 
    TSource value 
) 

おかげ

答えて

1

問題は、あなたがあなたのコードが無意味な表現o.Status.Contains(lst)を作成しようとしている、Expression.Callに二つの引数を切り替えているということです。あなたは周りの二つの引数を切り替える必要があり

Expression.Call(Expression.Constant(lst), 
    "Contains", 
    Type.EmptyTypes, 
    Expression.PropertyOrField(param, "Status")) 

これは、あなたが使用しているLINQプロバイダがList<T>.Contains()を理解することを想定しています。 Enumerable.Contains()が必要な場合は、Ivan Stoevの答えをご覧ください。

2

違いConvert Contains To Expression Treeからは、ここで我々が静的ジェネリックメソッドEnumerable.Containsを呼び出す必要がありながら、そこに私たちは、Contains方法stringインスタンスを呼んでいたということです別のものを使用して達成することができる。Expression.Call overload

このような

// Enumerable.Contains<byte?>(lst, a.Status) 
var containsCall = Expression.Call(
    typeof(Enumerable), // type 
    "Contains", // method 
    new Type[] { typeof(byte?) }, // generic type arguments (TSource) 
    Expression.Constant(lst), // arguments (source) 
    Expression.PropertyOrField(param, "Status") // arguments (value) 
); 
関連する問題