Прежде всего, я хотел бы отметить, что пары ключ-значение (модель AKA EAV) являются плохим выбором для представления данных такого типа, и этот вопрос является прекрасным примером того, почему - это намного, гораздо сложнее поиск произвольных наборов атрибутов, чем поиск конкретных свойств.
Конечно, это еще можно сделать:
var suitableProducts =
from p in products
where
p.Items.Any(s => s.Key == "dental" && s.Value == "true") &&
p.Items.Any(s => s.Key == "therapies" && s.Value == "false")
select p;
Это не так просто написать и эффективно, как запрос к классу Product
, который на самом деле имеет свойства dental
и therapies
, в отличие от вложенных атрибутов.
Если количество элементов, которое вам нужно запросить на , может измениться, то самый простой способ обработки, состоящий в том, чтобы связать воедино фильтры:
var searchItems = ...
var result = products;
foreach (var searchItem in searchItems)
{
result = result.Where(p =>
p.Items.Any(s => s.Key == searchItem.Key &&
s.Value == searchItem.Value));
}
// Do something with result
Если вы ищете более «функциональный» способ сделать это без цепочки, то:
var suitabilityConditions = searchItems.Select(i =>
(Predicate<Product>)(p => p.Items.Any(s =>
s.Key == searchItem.Key && s.Value == searchItem.Value)));
Predicate<Product> match = p => suitabilityConditions.All(c => c(p));
var suitableProducts = products.Where(match);