Recursively (?) Make LINQ predicates into a single predicate

(EDIT: I asked the wrong question. The real problem that I encountered is completed in Compose LINQ-to-SQL predicates into a single predicate - but this one got good answers, so I left it!)

Given the following search text:

"keyword1 keyword2 keyword3   ... keywordN"

I want to finish with the following 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%')

Effectively, we break the search text into spaces, trim each token, construct a sentence with several OR parts based on each token, and then AND'a along with the sentences.

I do this in Linq-to-SQL, and I have no idea how to dynamically compose a predicate based on an arbitrarily long list of sub-edits. For a known number of sentences, it is easy to manually predicate:

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. ?

+2
2

:

var query = dataContext.Customers;

do

foreach(string keyword in keywordlist)
{
    query = query.Where(Customer.Forenames.Contains(keyword) || Customer.Surname.Contains(keyword));
}
+3

, Aggregate foreach :

var query = keywordlist.Aggregate(dataContext.Customers, (q, keyword) => 
    q.Where(Customer.Forenames.Contains(keyword) || 
            Customer.Surname.Contains(keyword)); 

dataContext.Customers , () , ( Where, .

+1

All Articles