linq - 递归地 (?) 将 LINQ 谓词组合成单个谓词

标签 linq linq-to-sql recursion functional-programming composition

(编辑:我问了错误的问题。我遇到的真正问题已在 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/

相关文章:

linq - 使用Linq创建交叉表结果

c# - 按日期范围分组,在每个组内计数和排序 LINQ

c# - Linq to Xml : selecting elements if an attribute value equals a node value in an IEnumerable<XElement>

c# - 林克到 SQL : Sort Query by Arbitrary Property(Column) Name

.net - 优化 LINQ to SQL 查询的工具和技术

iOS7 Sprite Kit如何设置一系列依赖动画时序的 Action ?

c++ - 在 C++ 中验证二进制输入

linq - 将 Foreach 循环转换为 Linq 并出现错误

database - LINQ to SQL 用于自引用表?

C++ 多项式分布