シナリオは次のとおりです。Silverlight 4.0、DataGrid、PagedCollectionView アイテムソース。目的は、フィルターを PCV に適用することです。フィルターは - である必要がありますPredicate<object>(Method)
。ここで、メソッドはオブジェクトに対していくつかのロジックを実装し、含めるために true/false を返します。私が持っているのは、オプションでフィルター ロジックに 3 つの異なる基準を含める必要があり、明示的なコードはすぐに見苦しくなります。私たちはそれを望んでいませんよね?
したがって、PredicateBuilder を使用して式ツリーを構築し、それを Linq.Where に渡す方法があることがわかりました。
IQueryable<Product> SearchProducts (params string[] keywords)
{
var predicate = PredicateBuilder.False<Product>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or (p => p.Description.Contains (temp));
}
return dataContext.Products.Where (predicate);
}
[ちなみに、これは私がやろうとしていることではありません]
3 つのオプションの基準を使用して、次のようなものを書きたいと思います。
Ratings.Filter = BuildFilterPredicate(); // Ratings = the PagedCollectionView
private Predicate<object> BuildFilterPredicate()
{
bool FilterOnOrder = !String.IsNullOrEmpty(sOrderNumberFilter);
var predicate = PredicateBuilder.False<object>();
if (ViewMineOnly)
{
predicate = predicate.And(Rating r => sUserNameFilter == r.Assigned_To);
}
if (ViewStarOnly)
{
predicate = predicate.And(Rating r => r.Star.HasValue && r.Star.Value > 0);
}
if (FilterOnOrder)
{
predicate = predicate.And(Rating r => r.ShipmentInvoice.StartsWith(sOrderNumberFilter));
}
return predicate;
}
もちろん、PredicateBuilder はExpression<Func<T, bool>>
実際の述語メソッドではないものを作成するため、これはコンパイルされません。しかし、式ツリーをメソッドに変換する方法があることがわかったので、ネストされた if/then/else ステートメントの束に頼ることなく、目的を達成する方法があるはずだと私には思えました。
問題は、述語メソッドを動的に構築する方法はありますか?
ティア