#c# #lambda
#c# #лямбда
Вопрос:
Я не уверен, возможно ли это вообще, но следующий код работает:
searchDescriptor.Query(q => firstQuery || secondQuery || thirdQuery);
Но я передал их в свой метод из списка myOrQueries, поэтому мне нужно сделать что-то вроде:
List<Query> myOrQueries; // includes the 3 items above
// what I need is the correct way of doing the line below - if possible??
searchDescriptor.Query(q => myOrQueries[0] || myOrQueries[1] || myOrQueries[2]);
Возможно ли каким-либо образом выбрать каждый элемент и ИЛИ его?
Комментарии:
1. Вы имеете в виду объединение?
2. Нет, так не думаю. Мне нужно иметь возможность делать что-то вроде:
q => myOrQueries.ForEach(||)
или подобное. В основном OR’ing список.
Ответ №1:
Ну, умный поставщик LINQ сможет работать с массивом напрямую, что-то вроде этого:
searchDescriptor.Query(q => myOrQueries.Any())
Если этого недостаточно, вам просто нужно объединить эти запросы вместе с помощью OrElse
и использовать их как единый предикат в Where
исходном searchDescriptor.
Это немного длинновато, поэтому я просто отсылаю вас к PredicateBuilder
вспомогательному классу Джо Альбахари:http://www.albahari.com/nutshell/predicatebuilder.aspx
Это помогает добавлять их в качестве методов расширения IQueryable
, они довольно удобны 🙂
Редактировать:
Простое решение, которое работает:
BaseQuery variableQuery = null;
if (roleStatuses != null amp;amp; roleStatuses.Any())
{
foreach (string roleStatus in roleStatuses)
{
var status = roleStatus;
var subQuery =
new QueryDescriptor<MySearchDataContract>()
.Match(s => s.OnField(o => o.Roles.First().RoleStatus)
.QueryString(status));
variableQuery = variableQuery == null ? subQuery : variableQuery || subQuery;
}
}
Комментарии:
1.
Any
будет проверяться только то, что в списке что-то есть, предполагая, что каждый элемент является фактическим запросом, тогда их, вероятно, потребуется выполнить, напримерAny(x => x())
.2.
searchDescriptor.Query(q => myOrQueries.Any())
будет соответствовать каждому элементу до тех пор,myOrQueries
пока есть хотя бы один элемент. Это должно бытьsearchDescriptor.Query(q => myOrQueries.Any(x => x(q))
3. Ну, я понятия не имею, что это за запросы, поэтому я не могу написать «полностью правильный» код, я просто излагаю рассуждения. Скорее всего, что-то вроде
searchDescriptor.Query(q => possibleValues.Contains(q.SomeField)
будет лучше.4. @Luaan Я думаю, проблема в том, что вы предполагаете, что
Any
это должно просто «работать», когда на самом деле всеAny
определяет, что в списке есть что -то, это никоим образом не оценивает значение этого конкретного элемента в списке (что и ищет OP).5. .Any() — это не то, что я ищу. Смотрите мою первую строку (которая работает) — мне нужно получить тот же результат, используя список. Я попробую PredicateBuilder и дам вам знать. Спасибо
Ответ №2:
Благодаря комментариям от Luaan — лямбда была недоступна, но простой способ построить выражение работает:
BaseQuery variableQuery = null;
if (roleStatuses != null amp;amp; roleStatuses.Any())
{
foreach (string roleStatus in roleStatuses)
{
var status = roleStatus;
var subQuery = new QueryDescriptor<MySearchDataContract>()
.Match(s => s.OnField(o => o.Roles.First().RoleStatus)
.QueryString(status));
variableQuery = variableQuery == null ? subQuery : variableQuery || subQuery;
}
}