2010-12-13 11 views
2

OK LINQを取得するには、汎用からキャストすることはできませんので、私は次の関数書いている:

private IQueryable<LogEntry> SelectAll<T>(IEnumerable<LogEntry> logEntries, List<Expression<Func<LogEntry, bool>>> whereClause) 
{ 
    var selectAllQuery = from l in logEntries select l; 
    if (whereClause != null) 
    { 
     foreach (Expression<Func<LogEntry, bool>> whereStatement in whereClause) 
     { 
      selectAllQuery = selectAllQuery.Where(whereClause); 
     } 
    } 
} 

をしかし、それはコンパイルされません。以下のように、それは「selectAllQuery」で何かを返そうとする場合には、エラーがスローされます。

System.Collections.Generic.IEnumerableは 『と最高の拡張メソッドのオーバーロード System.Linqの」の定義が含まれていません』 .Enumerable.Where(System.Collections.Generic.IEnumerable、System.Func)は、」私はこれを鋳造し、私は無駄に考えることができるすべてのどの方法を試してみたいくつかの無効な引数

を持っています。上記のコードでは、最初のselectステートメントを実行するとSystem.Linq.Enumerable.WhereSelectEnumerableIterator<LogEntry,LogEntry>

のタイプの返す明らかに私はLINQについて何か基本的なものを欠いています。しかし何?

乾杯。

答えて

5

selectAllQueryIEnumerable<LogEntry>であり、式ツリーを使用するにはIQueryable<LogEntry>である必要があります。

foreach (Expression<Func<LogEntry, bool>> whereStatement in whereClause) 
{ 
    selectAllQuery = selectAllQuery.Where(whereStatement.Compile()); 
} 

EDIT::さて、問題は、という理由だけではありませんでしたあなたは、デリゲートのフォームにそれらを得るために行くように述語をコンパイルし、また

var selectAllQuery = logEntries.AsQueryable(); 

:ちょうどメソッドの最初の行を変更してみてくださいQueryableの名前ですが、あなたの名前のためです。のは、このforeachの文を見てみましょう:あなたはループ本体内のどこwhereStatementを使用していない

foreach (Expression<Func<LogEntry, bool>> whereStatement in whereClause) 
{ 
    selectAllQuery = selectAllQuery.Where(whereClause); 
} 

。あなたはWhereに各反復の句のリスト全体を呼び出すことを試みています。これは、より良い命名が役立つところです。例えば、これを試してみてください:

private IQueryable<LogEntry> SelectAll<T>(IEnumerable<LogEntry> logEntries, 
    List<Expression<Func<LogEntry, bool>>> filters) 
{ 
    var selectAllQuery = logEntries.AsQueryable(); 
    if (filters != null) 
    { 
     foreach (var filter in filters) 
     { 
      selectAllQuery = selectAllQuery.Where(filter); 
     } 
    } 
    return selectAllQuery; 
} 

パラメータは現在複数形であるので、それはWhereメソッドの引数として間違っ明らかを見てしまう - whereStatementwhereClause間の差がで明らか全てではないのに対し、前者は単数であり、後者は複数であるからである。

+0

ええ、そうです。 – jason

+0

どちらもうまくいかないようです。 Intellisenseに従ってwhereClauseで "Compile"メソッドを使用できず、varをAsQueryable()に変更すると、同様のエラーが発生する - エラー 'System.Linq.IQueryable 'に 'Where'の定義が含まれていないベストエクステンションメソッドのオーバーロード 'System.Linq.Enumerable.Where (System.Collections.Generic.IEnumerable 、System.Func )'に無効な引数がいくつかあります。私は実際にそれが明白な解決策に見えるように投稿する前にAsQueryableを試しました。 –

+0

@Matt:申し訳ありませんが、それは 'whereStatement。コンパイル ' - そして元のコードでループの本体で' whereStatement'を使用したが、AsQueryableを使用した場合、それはうまくいったでしょう。提案された名前の変更で編集します... –

1

これらの種類のエラーは、System.Linqをプロジェクトに追加してクラスファイルを参照するような単純な解決策で取り除かれることがあります。 VS IDEがリファクタリングメニューの一部として解決するのを助けないのは非常に悲しいです...