Linq to Entities 中的动态 where 子句 (OR) [英] Dynamic where clause (OR) in Linq to Entities
问题描述
在帖子这里中,我学会了如何构建动态使用 Linq 的延迟执行进行查询.但查询实际上使用了 WHERE 条件的 AND 连接.
In the post here I learned how to build a dynamic query using the deferred execution of Linq. But the query is actually using an AND concatenation of the WHERE condition.
如何使用 OR 逻辑实现相同的查询?
由于 Flags 枚举,查询应该搜索 Username、WindowsUsername 或 两者:
Due to the Flags enum, the query should search for Username, WindowsUsername or both:
public User GetUser(IdentifierType type, string identifier)
{
using (var context = contextFactory.Invoke())
{
var query = from u in context.Users select u;
if (type.HasFlag(IdentifierType.Username))
query = query.Where(u => u.Username == identifier);
if (type.HasFlag(IdentifierType.Windows))
query = query.Where(u => u.WindowsUsername == identifier);
return query.FirstOrDefault();
}
}
推荐答案
With LINQKit 的PredicateBuilder 您可以动态构建谓词.
With LINQKit's PredicateBuilder you can build predicates dynamically.
var query = from u in context.Users select u;
var pred = Predicate.False<User>();
if (type.HasFlag(IdentifierType.Username))
pred = pred.Or(u => u.Username == identifier);
if (type.HasFlag(IdentifierType.Windows))
pred = pred.Or((u => u.WindowsUsername == identifier);
return query.Where(pred.Expand()).FirstOrDefault();
// or return query.AsExpandable().Where(pred).FirstOrDefault();
这就是 Expand
的用途:
Entity Framework 的查询处理管道无法处理调用表达式,这就是您需要在查询中的第一个对象上调用 AsExpandable 的原因.通过调用 AsExpandable,您可以激活 LINQKit 的表达式访问者类,该类将调用表达式替换为实体框架可以理解的更简单的构造.
Entity Framework's query processing pipeline cannot handle invocation expressions, which is why you need to call AsExpandable on the first object in the query. By calling AsExpandable, you activate LINQKit's expression visitor class which substitutes invocation expressions with simpler constructs that Entity Framework can understand.
或者:没有它的表达式是 Invoke
d,这会导致 EF 中的异常:
Or: without it an expression is Invoke
d, which causes an exception in EF:
LINQ to Entities 不支持 LINQ 表达式节点类型Invoke".
The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
后期补充:
有一个替代的谓词构建器,它的功能相同但没有扩展:http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/
There is an alternative predicate builder that does the same but without Expand: http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/
这篇关于Linq to Entities 中的动态 where 子句 (OR)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!