Linq到实体中的动态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逻辑?
由于标志枚举,查询应该搜索用户名, 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();
}
}
推荐答案
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();
这是展开
是为:
实体框架的查询处理流水线无法处理调用表达式,这就是为什么您需要在查询中的第一个对象上调用AsExpandable的方法。通过调用AsExpandable,激活LINQKit的表达式访问类,代替调用表达式具有Entity Framework可以理解的更简单的构造。
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.
La另外:
有一个替代的谓词构建器执行相同但没有展开: 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到实体中的动态where子句(OR)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!