Поскольку вы работаете с LINQ, я полагаю, вы работаете с контекстом данных LINQ-to-SQL? У меня нет запасного DataContext, чтобы проверить это, но это должно дать вам некоторые идеи.
Я не знаю, будет ли он работать с контекстом данных, но большинство из них довольно простые (привязка оператора OR и вызов метода Contains), поэтому он не должен вызывать проблемы, когда запрос переводится в SQL.
Сначала я создать пользовательскую функцию, которая будет строить свой предикат:
Func<string, Func<DataItem, bool>> buildKeywordPredicate =
keyword =>
x => x.Title.Contains(keyword)
|| x.Contents.Contains(keyword);
Это функция, которая принимает один строковый ключевое слово, а затем возвращать другую функцию, которая принимает DataItem и проверяет его против ключевого слова.
В принципе, если вы перейдете в «Stack», вы получите предикат: x => x.Title.Contains("Stack") || x.Contents.Contains("Stack")
.
Далее, поскольку существует много возможных ключевых слов, и вы должны приковать его с операцией ИЛИ, я создаю еще одну вспомогательную функцию в цепи 2 предикаты вместе с ИЛИ
Func<Func<DataItem,bool>, Func<DataItem, bool>, Func<DataItem, bool>> buildOrPredicate =
(pred1, pred2) =>
x => pred1(x) || pred2(x);
Эта функция принимает 2 предикаты, а затем присоедините их к операции ИЛИ.
Имея эти 2 функции, я могу затем построить мой, где предикат, как это:
foreach (var word in keywords) {
filter = filter == null
? buildKeywordPredicate(word)
: buildOrPredicate(filter, buildKeywordPredicate(word));
}
Первая строка внутри цикла в основном проверяет, если фильтр является недействительным. Если да, то мы хотим, чтобы для нас был создан простой фильтр ключевых слов.
Иначе, если фильтр не является нулевым, нам необходимо связать существующие фильтры с операцией ИЛИ, поэтому мы передаем существующий фильтр и новый фильтр ключевых слов для созданияOrPredicate, чтобы сделать именно это.
И тогда мы можем теперь создать где часть запроса:
var result = data.Where(filter);
Passing в сложном предикате мы только что создали.
Я не знаю, будет ли это отличаться от использования PredicateBuilder, но поскольку мы откладываем перевод запросов к движку LINQ-to-SQL, проблем не должно быть.
Но, как я уже сказал, я не тестировал его в реальном контексте данных, поэтому, если есть какие-либо проблемы, вы можете написать в комментариях.
Вот консоль приложение, которое я построил для теста: http://pastebin.com/feb8cc1e
Надеется, что это помогает!
EDIT: Для более общего и многократного использования версии, которая включает в себя должным образом с использованием деревьев выражений в LINQ, проверить блоге Томаса Petricek в: http://tomasp.net/articles/dynamic-linq-queries.aspx
Это будет работать только к сожалению для функций. Чтобы сделать эту работу с деревьями выражений, вам нужно использовать трюк, подобный этому: http://tomasp.net/articles/dynamic-linq-queries.aspx –
Это какой-то подвиг, который вы там сделали! .. Тот же трюк, но более общий и еще больше удивительности ... Во всяком случае, я подписчик вашего блога сейчас :-) – chakrit
Спасибо, этот работал. http://tomasp.net/articles/dynamic-linq-queries.aspx - Tomas Petricek – Amir