(РЕДАКТИРОВАТЬ: Я задал неправильный вопрос. У меня проблема real закончилась на Объединить предикаты LINQ-to-SQL в один предикат - но этотполучил несколько хороших ответов, поэтому я оставил это!)
Учитывая следующий текст поиска:
"keyword1 keyword2 keyword3 ... keywordN"
Я хочу получить следующий SQL:
SELECT [columns] FROM Customer
WHERE
(Customer.Forenames LIKE '%keyword1%' OR Customer.Surname LIKE '%keyword1%')
AND
(Customer.Forenames LIKE '%keyword2%' OR Customer.Surname LIKE '%keyword2%')
AND
(Customer.Forenames LIKE '%keyword3%' OR Customer.Surname LIKE '%keyword3%')
AND
...
AND
(Customer.Forenames LIKE '%keywordN%' OR Customer.Surname LIKE '%keywordN%')
По сути, мы разбиваем текст поиска на пробелы, обрезаем каждый токен, строим предложение OR из нескольких частей на основе каждого токена, а затем объединяем предложения AND.
Я делаюэто в Linq-to-SQL, и я понятия не имею, как динамически составлять предикат на основе произвольно длинного списка субпредикатов.Для известного количества предложений легко составить предикаты вручную:
dataContext.Customers.Where(
(Customer.Forenames.Contains("keyword1") || Customer.Surname.Contains("keyword1")
&&
(Customer.Forenames.Contains("keyword2") || Customer.Surname.Contains("keyword2")
&&
(Customer.Forenames.Contains("keyword3") || Customer.Surname.Contains("keyword3")
);
, но я хочу обработать произвольный список поисковых терминов.Я дошел до
Func<Customer, bool> predicate = /* predicate */;
foreach(var token in tokens) {
predicate = (customer
=> predicate(customer)
&&
(customer.Forenames.Contains(token) || customer.Surname.Contains(token));
}
, который создает исключение StackOverflowException - предположительно потому, что предикат () в RHS назначения фактически не оценивается до времени выполнения, после чего он в конечном итоге вызывает сам себя ...или что-то в этом роде.
Короче говоря, мне нужен метод, который при двух предикатах возвращает один предикат, составляющий два исходных предиката с предоставленным оператором, но ограниченный операторами, явно поддерживаемыми Linq-to-SQL.,Есть идеи?