将 LINQ-to-SQL 谓词组合成单个谓词
(之前的问题,递归地(?)将 LINQ 谓词组合成单个谓词 解决方案满足了所提出的问题,但实际上并不是我所需要的。但老实说。)
,与此类似,但我实际上问了错误的问题...那里的 text:
"keyword1 keyword2 ... keywordN"
我想最终得到以下 SQL:
SELECT [columns] FROM Customer
WHERE (
Customer.Forenames LIKE '%keyword1%'
OR
Customer.Forenames LIKE '%keyword2%'
OR
...
OR
Customer.Forenames LIKE '%keywordN%'
) AND (
Customer.Surname LIKE '%keyword1%'
OR
Customer.Surname LIKE '%keyword2%'
OR
....
OR
Customer.Surname LIKE '%keywordN%'
)
实际上,我们在空格上分割搜索文本,修剪每个标记,基于每个 构造一个多部分 OR 子句,然后将这些子句进行 AND 运算。
我在 Linq-to-SQL 中执行此操作,但我不知道如何基于任意长的子谓词列表动态组合谓词。对于已知数量的子句,手动组合谓词很容易:
dataContext.Customers.Where(
(
Customer.Forenames.Contains("keyword1")
||
Customer.Forenames.Contains("keyword2")
) && (
Customer.Surname.Contains("keyword1")
||
Customer.Surname.Contains("keyword2")
)
);
简而言之,我需要一种技术,在给定两个谓词的情况下,将返回用提供的运算符组成两个源谓词的单个谓词,但仅限于显式支持的运算符通过 Linq-to-SQL。有什么想法吗?
(An earlier question, Recursively (?) compose LINQ predicates into a single predicate, is similar to this but I actually asked the wrong question... the solution there satisfied the question as posed, but isn't actually what I need. They are different, though. Honest.)
Given the following search text:
"keyword1 keyword2 ... keywordN"
I want to end up with the following SQL:
SELECT [columns] FROM Customer
WHERE (
Customer.Forenames LIKE '%keyword1%'
OR
Customer.Forenames LIKE '%keyword2%'
OR
...
OR
Customer.Forenames LIKE '%keywordN%'
) AND (
Customer.Surname LIKE '%keyword1%'
OR
Customer.Surname LIKE '%keyword2%'
OR
....
OR
Customer.Surname LIKE '%keywordN%'
)
Effectively, we're splitting the search text on spaces, trimming each token, constructing a multi-part OR clause based on each , and then AND'ing the clauses together.
I'm doing this in Linq-to-SQL, and I have no idea how to dynamically compose a predicate based on an arbitrarily-long list of subpredicates. For a known number of clauses, it's easy to compose the predicates manually:
dataContext.Customers.Where(
(
Customer.Forenames.Contains("keyword1")
||
Customer.Forenames.Contains("keyword2")
) && (
Customer.Surname.Contains("keyword1")
||
Customer.Surname.Contains("keyword2")
)
);
In short, I need a technique that, given two predicates, will return a single predicate composing the two source predicates with a supplied operator, but restricted to the operators explicitly supported by Linq-to-SQL. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用
PredicateBuilder
类(这实际上是来自
PredicateBuilder
页面,我只是根据您的情况进行了调整...)编辑:
实际上我误读了您的问题,上面的示例仅涵盖了解决方案的一部分...以下方法应该执行以下操作你想要:
你可以这样使用它:
You can use the
PredicateBuilder
class(that's actually the example from the
PredicateBuilder
page, I just adapted it to your case...)EDIT:
Actually I misread your question, and my example above only covers a part of the solution... The following method should do what you want :
You can use it like that:
通常,您会链接调用
.Where(...)
。例如:LINQ-to-SQL 会将其全部焊接到一个
WHERE
子句中。但是,这不适用于
OR
。您可以使用并集和交集,但我不确定 LINQ-to-SQL(或 SQL Server)是否足够聪明,可以将其折叠回单个WHERE
子句。 OTOH,如果性能不受影响,那也没关系。无论如何,它看起来像这样:Normally you would chain invocations of
.Where(...)
. E.g.:LINQ-to-SQL would weld it all back together into a single
WHERE
clause.This doesn't work with
OR
, however. You could use unions and intersections, but I'm not sure whether LINQ-to-SQL (or SQL Server) is clever enough to fold it back to a singleWHERE
clause. OTOH, it won't matter if performance doesn't suffer. Anyway, it would look something like this: