簡単にするために、次の 2 つのクラスがあると仮定します。
public class ComplexClass
{
public List<SubClass> SubClasses { get; set; }
public string Name { get; set; }
}
public class SubClass
{
public string Name { get; set; }
}
があり、List<ComplexClass>
いくつかのパラメーターに基づいてクエリを作成する必要があります。
Name
のプロパティを使用するだけでよい場合は、簡単な作業ですComplexClass
。次に例を示します。
static IQueryable<ComplexClass> GetQuery(string someParameter, string someOtherParameter)
{
var query = list.AsQueryable();
if (!String.IsNullOrEmpty(someParameter))
query = query.Where(c => c.Name.StartsWith(someParameter));
if (!String.IsNullOrEmpty(someOtherParameter))
query = query.Where(c => c.Name.EndsWith(someOtherParameter));
return query;
}
私が持っているパラメーターに基づいて、さらにクエリ要素を追加できます。もちろん、上記の例は単純ですが、実際の問題にはさらに多くのパラメーターが含まれており、その数は増える可能性があります。
パラメータに基づく基準を満たすComplexClass
インスタンスを持つインスタンスを見つけたい場合、物事はそれほど単純ではありません。SubClass
static IQueryable<ComplexClass> GetSubQuery(string someParameter, string someOtherParameter)
{
var query = list.AsQueryable();
if (!String.IsNullOrEmpty(someParameter))
if (!String.IsNullOrEmpty(someOtherParameter))
return query.Where(c => c.SubClasses.Where(sc => sc.Name.StartsWith(someParameter) && sc.Name.EndsWith(someOtherParameter)).Any());
else
return query.Where(c => c.SubClasses.Where(sc => sc.Name.StartsWith(someParameter)).Any());
else
if (!String.IsNullOrEmpty(someOtherParameter))
return query.Where(c => c.SubClasses.Where(sc => sc.Name.EndsWith(someOtherParameter)).Any());
else
return null;
}
各パラメーターに基づいてクエリのビットを追加するだけでは済みません。クエリ全体を一度に記述する必要があります。これは、パラメーターのすべての組み合わせをチェックする必要があることを意味しますが、これは理想的ではありません。
クラスを構築し、そこからラムダ式を作成することが重要Expression
だと思いますが、問題に取り組む方法がわかりません。
助言がありますか?:)
編集:
私の最初のアイデアはこれでした:
static IQueryable<ComplexClass> GetSubQuery(string someParameter, string someOtherParameter)
{
var query = list.AsQueryable();
query = query.Where(c =>
{
var subQuery = c.SubClasses.AsQueryable();
if (!String.IsNullOrEmpty(someParameter))
subQuery = subQuery.Where(sc => sc.Name.StartsWith(someParameter));
if (!String.IsNullOrEmpty(someOtherParameter))
subQuery = subQuery.Where(sc => sc.Name.EndsWith(someOtherParameter));
return subQuery.Any();
});
return query;
}
これは、LINQ to Objects を使用しているため、私の小さなコンソール テスト アプリケーションで機能します。残念ながら、Entity Framework と LINQ to Entities を使用する必要があるため、上記のような実装でA lambda expression with a statement body cannot be converted to an expression tree
エラー メッセージがスローされます。