(编辑:我问了错误的问题。我遇到的真正问题已在 Compose LINQ-to-SQL predicates into a single predicate 结束 - 但这个问题得到了一些很好的答案,所以我把它留下了!)
给定以下搜索文本:
"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 上的 predicate() 直到运行时才真正被评估,此时它最终会调用自己......或者其他东西。
简而言之,我需要一种技术,在给定两个谓词的情况下,将返回由两个源谓词与提供的运算符组成的单个谓词,但仅限于 Linq-to-SQL 显式支持的运算符。有什么想法吗?
最佳答案
我建议另一种技术
你可以这样做:
var query = dataContext.Customers;
然后,在一个循环内执行
foreach(string keyword in keywordlist)
{
query = query.Where(Customer.Forenames.Contains(keyword) || Customer.Surname.Contains(keyword));
}
关于linq - 递归地 (?) 将 LINQ 谓词组合成单个谓词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3782799/