使用PredicateBuilder(来自 LinqPad 的作者),您可以根据一组编译时未知的条件构建查询。以下内容就足够了:
var predicate = PredicateBuilder.True<Product>();
foreach (Suitability criteria in searchCriteria)
{
string tempKey = criteria.Key;
string tempValue = criteria.Value;
predicate = predicate.And(p =>
p.Items.Any(s => s.Key == tempKey && s.Value == tempValue));
}
return dataContext.Products.Where(predicate.Compile());
更新:这是我测试过的一些示例代码,它使用 IEnumerable 作为源,结果集 productsResult 包含 products 列表中的第一个和第二个产品:
var searchCriteria = new List<Suitability>()
{
new Suitability() { Key="a", Value="b" },
new Suitability() { Key="a", Value="c" }
};
var products = new List<Product>()
{
new Product()
{
Items = new List<Suitability>() {
new Suitability() { Key="a", Value="b" },
new Suitability() { Key="a", Value="c" }}
},
new Product()
{
Items = new List<Suitability>() {
new Suitability() { Key="a", Value="b" },
new Suitability() { Key="a", Value="c" },
new Suitability() { Key="b", Value="c" }}
},
new Product()
{
Items = new List<Suitability>() {
new Suitability() { Key="c", Value="d" }}
}
};
var predicate = PredicateBuilder.True<Product>();
foreach (Suitability criteria in searchCriteria)
{
string tempKey = criteria.Key;
string tempValue = criteria.Value;
predicate = predicate.And(p => p.Items.Any(
s => s.Key == tempKey && s.Value == tempValue));
}
IEnumerable<Product> productsResult = products.Where(predicate.Compile());