Для вызова API у меня есть строка, отправляемая для получения соответствующих предметов инвентаря. Следующее работает по назначению:
public IEnumerable<Inventory> GetInventoryByItem(string item)
{
return _ctx.Pairs
.Include(x => x.Attribute)
.Where(x => (x.Attribute.Item == item));
}
Моя проблема заключается в том, чтобы добавить несколько условий к функции, чтобы получить что-то в результате:
public IEnumerable<Inventory> GetInventoryByItem(string[] items)
{
return _ctx.Pairs
.Include(x => x.Attribute)
.Where(x => foreach(string item in items){ return x.Attribute.Item == item });
}
Вышеуказанная функция явно не работает. Я знаю, что могу получить коллекцию элементов, вызвав вышеуказанную функцию извне в цикле, но меня беспокоит то, что я попадаю в базу данных с несколькими почти идентичными операторами, когда я мог бы просто объединить их в один. Есть ли эффективный способ сделать это?
.Where(x => items.Contains(x.Attribute.Item)); или .Where(x => items.Any(item => x.Attribute.Item == item));@NetMage, о, верно! спасибо, удалил





Итак, вам нужна универсальная функция, которая принимает на вход последовательность объектов некоторого класса и последовательность предикатов свойств этого класса, и вы хотите на выходе последовательность, содержащую эти объекты из входной последовательности, где все предикаты возвращали бы true
Например:
IEnumerable<Person> persons = ...
var predicates = [0] person is born in 1961
[1] person is born in Honolulu
[2] person is a politician
В качестве вывода вам нужна последовательность со всеми политиками, родившимися в Гонолулу в 1961 году.
Давайте сделаем это как метод расширения, чтобы вы могли использовать его как инструкцию LINQ. См. демистифицированные методы расширения
Что вы делаете, так это объединяете утверждения Where. Параметр predicate, где Func<TSource, bool>. Итак, нам нужна последовательность Func<TSource, bool> в качестве предикатов.
static IEnumerable<TSource> Where( this IEnumerable<TSource> source,
IEnumerable<Func<TSource, bool>> predicates)
{
// TODO: handle null source and null predicates
IEnumerable<TSource> result = source;
foreach (Func<TSource, bool> predicate in predicates)
{
result = result.Where(predicate);
}
return result;
}
Пример использования:
IEnumerable<Person> persons = ...
var honoluluPresidents = persons.Where(new[]
{
person => person.BirthPlace == "Honolulu",
person => person.BirthDate.Year == 1961,
person => person.Job == "politician",
});
Просто comme bonjour!
Но чем это лучше, чем сочетание предикатов с и/или? Я также думаю, что вы что-то упустили (например, []) в своем примере использования.
Что ж, это был ваш выбор не предоставлять вариант использования, когда программное обеспечение выдает неизвестную последовательность предикатов. Возможно, оператор создал список предикатов, выбрав предикаты из поля выбора. Ваше предложение использовать последовательность строк еще хуже, потому что нет абсолютно никакой проверки того, что используемые строки представляют правильные предикаты. Вы правы насчет [] . Не стесняйтесь улучшить ответ
Я не говорил о строках — я говорил о логических операторах «&&» и «||».
Тем не менее, в своем вопросе вы пишете GetInventoryByItem(string[] items), я предположил, что вы хотите идентифицировать предикаты в вашем where, используя последовательность строк. Если это не так, то что вы имели в виду?
Но это не мой вопрос :D, ОП - это @анестетик. Я думаю, что он хотел сделать, это отфильтровать набор чего-то x на основе того, имеет ли этот x все атрибуты элемента, переданные в качестве параметра.
Ну, вы можете использовать Any
public IEnumerable<Inventory> GetInventoryByItem(string[] items)
{
return _ctx.Pairs
.Include(x => x.Attribute)
.Where(x => items.Any(a=> a == x.Attribute.Item));
// OR
return _ctx.Pairs
.Include(x => x.Attribute)
.Where(x => items.Contains(x.Attribute.Item));
}
Может быть, вы имели в виду .All() под своим foreach?
public IEnumerable<Inventory> GetInventoryByItems(string[] items)
{
return _ctx.Pairs
.Include(x => x.Attribute)
.Where(x => items.All(item => x.Attribute.Item == item));
}
Используйте
items.Containsвнутри предложениеWhere.