私はPredicateBuilderが本当に好きです。これにより、あらゆる種類のクエリを非常に動的に構築できます。述語変数はさまざまなオブジェクトに渡すことができ、それらは知っている値などを追加できます。ハッシュされたコレクションに.Containsを使用する必要がある場合を除きます。Bzzt!クラッシュして燃えます。
たとえば(例/擬似コード、これはコンパイル/実行される場合とされない場合があります):
protected Expression<Func<MyClass, bool>> GetWherePredicate()
{
string[] selectedValues = Request.Form.GetValues("checkbox1") ?? new string[0];
HashSet<int> selectedIDs = new HashSet<int>(selectedValues.Cast<int>());
Expression<Func<MyClass, bool>> predicate = PredicateBuilder.True<MyClass>();
predicate = predicate.And(s => selectedIDs.Contains(s.ID));
return predicate;
}
protected void Retrieve()
{
Expression<Func<MyClass, bool>> predicate = GetWherePredicate();
IEnumerable<MyClass> retrievedValues = MyDataContext.GetTable<MyClass>.Where(predicate);
}
これを実行しようとすると、NotSupportedExceptionが発生します。メソッド'Boolean contains(Int32)'は、selectedIDs HashSetがスコープ内にないため、SQLへの変換がサポートされていません。これをすべて同じ方法で行うと、正常に機能します。
HashSetが宣言されている場所とは異なるスコープで使用できるように、述語を解決またはコンパイルするための正しい方法を知る必要があります。何か助けはありますか?
更新:私はこれをかなり間違っていました。以下のコードは正常に機能するため、スコープの競合はありません。ジェイありがとう。
string[] selectedValues = Request.Form.GetValues("checkbox1") ?? new string[0];
Expression<Func<MyClass, bool>> predicate = PredicateBuilder.True<MyClass>();
predicate = predicate.And(s => selectedValues.Contains(s.ID.ToString()));