2011-11-15 4 views
3

基本的にエントリーのリストを提供するクラスを作成したいと思います。このエントリは、データベースから読み取ることも、アプリケーションの存続期間中に生成することもできます。このクラスは、このエントリをフィルタリングする方法を提供する必要があります。両方のソースに対して1つのフィルタしか必要としないようにフィルタを実装することは可能ですか?例えばLinq-To-Entitesに動的フィルターを適用してサーバー側を実行する方法

interface IFilter 
{ 
    bool Filter(ILogEntry entry); 
} 

は、IEnumerableを持つLINQのために、このような動的フィルタを適用するには問題はありません。

IEnumerable<IFilter> filters; 
IEnumerable<ILogEntry> entries; 

foreach(var filter in filters) 
    entries = entries.Where(p => filter.Filter(p)); 

しかし、LINQのツーSQLの私はのための解決策がない二つの問題があります。ILogEntryにコンテキストが提供するログ・エントリを変換するにはどうすればよい

  1. は?
  2. クエリはサーバー上で実行され、ローカルでは実行されません。

次のコードは実際にサーバー上でフィルタを実行するということは少し奇妙なようです。私は、フィルタは、クライアント側で適用される引数として(ログ・エントリで実装されている)ILogEntryをとり、このクエリでのIFilterを使用している場合でも:

entities.Logs 
    .Select(p => new LogEntry() { Message = p.Message }) 
    .Where(p => p.Message == "132"); 

はいるICollectionとのIQueryableのフィルタを書くための方法はありますし、 SQL Server上でIQueryable用のフィルタが実行されることを確認しますか?

public Expression<Func<ILogEntry, bool>> GetPredicate() { 
    return x => x.SomeField == 25; 
} 

注:これは、その後のような実装を必要と

interface IFilter { 
    public Expression<Func<ILogEntry, bool>> GetPredicate(); 
} 
... 
IQueryable<ILogEntry> entries = ... 
foreach(var filter in filters) { 
    entries = entries.Where(filter.GetPredicate()); 
} 

答えて

3

そのサーバ側を適用する唯一の方法は、例えば、式ツリーとしてを構成することであるあなたの場合メモリ内に隙間があり、からIQueryable<T>.AsQueryable()を使用して切り替えることができます。これにより、式ツリーをローカルで使用できます。

+0

ありがとう、この回答は非常に便利でした。 – SACO

関連する問題