2011-10-22 13 views
6

式ツリーを作成しようとしています。データテーブルからデータを読み込み、その列をチェックする必要があります。チェックされる列とチェックされる列の数は、実行時にのみ認識されます。列名は文字列配列として私に与えられ、各列にはチェックされる文字列のリストがあります。私は以下のようなサンプル表現ツリーを試しました。ERROR静的メソッドにはnullインスタンスが必要です。非静的メソッドにはnull以外のインスタンスが必要です

ここでエラーが発生しました。

静的メソッドにはnullインスタンスが必要です。非静的メソッドにはnull以外のインスタンスが必要です。 パラメータ名:インスタンス

線で

= Expression.Call(rowexp、MI、colexp)インナー。

親切に私を助けてください!

IQueryable<DataRow> queryableData = CapacityTable 
    .AsEnumerable() 
    .AsQueryable() 
    .Where(row2 => values.Contains(row2.Field<string>("Head1").ToString()) 
       && values.Contains(row2.Field<string>("Head2").ToString())); 

MethodInfo mi = typeof(DataRowExtensions).GetMethod(
    "Field", 
     new Type[] { typeof(DataRow),typeof(string) }); 

mi = mi.MakeGenericMethod(typeof(string)); 

ParameterExpression rowexp = Expression.Parameter(typeof(DataRow), "row"); 
ParameterExpression valuesexp = Expression.Parameter(typeof(List<string>), "values"); 
ParameterExpression fexp = Expression.Parameter(typeof(List<string>), "types"); 
Expression inner, outer, predicateBody = null; 

foreach (var col in types) 
{ 
    // DataRow row = CapacityTable.Rows[1]; 

    ParameterExpression colexp = Expression.Parameter(typeof(string), "col"); 
    // Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes)); 

    inner = Expression.Call(rowexp,mi, colexp); 
    outer = Expression.Call(valuesexp, typeof(List<string>).GetMethod("Contains"), inner); 
    predicateBody = Expression.And(predicateBody,outer); 
} 

MethodCallExpression whereCallExpression = Expression.Call(
    typeof(Queryable), 
    "Where", 
    new Type[] { queryableData.ElementType }, 
    queryableData.Expression, 
    Expression.Lambda<Func<DataRow,bool>>(predicateBody, new ParameterExpression[] { rowexp })); 

答えて

9

これは、表示しようとしているメソッド呼び出しが静的なものであることを意味しますが、ターゲット式を指定しています。それは呼び出ししようとしているようなものだ:あなたはソートのいずれかの許可されていない式ツリーの形でそれをやろうとしている

Thread t = new Thread(...); 
// Invalid! 
t.Sleep(1000); 

。それはこのようになります

DataRowExtensionsField拡張メソッドのために起こっている - ので、あなたが実際に呼び出したいので、拡張メソッドの「標的」は、コールの最初の引数として表現する必要があります

DataRowExtensions.Field<T>(row, col); 

だから、あなたが欲しい:二つの引数を持つ静的メソッドを呼び出す方法であるthis overloadを呼び出します

inner = Expression.Call(mi, rowexp, colexp); 

+0

上記の内容を少し詳しく説明できますか?ここでExpression.Callメソッドの最初の引数としてMethod情報を渡すのはなぜですか? – Kobojunkie

+0

@Kobojunkie:これは、Expression.Callに私たちが興味を持っている静的メソッドを伝える方法です。http://msdn.microsoft.com/en-us/library/bb301084.aspxを参照してください。 –

関連する問題