在本文中,我学习了如何使用Linq的延迟执行来构建动态查询。但是查询实际上是使用WHERE条件的 AND 串联。
如何使用OR逻辑实现相同的查询?
由于Flags枚举,查询应搜索 Username , WindowsUsername 或 两者 :
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,您可以动态地构建谓词。
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是为了:
Expand
实体框架的查询处理管道无法处理调用表达式,这就是为什么您需要在查询中的第一个对象上调用AsExpandable的原因。通过调用AsExpandable,您可以激活LINQKit的表达式访问者类,该类将调用表达式替换为Entity Framework可以理解的更简单的结构。
或者:如果没有它,则表达式为Invoked,这将导致EF中的异常:
Invoke
LINQ to Entities不支持LINQ表达式节点类型’Invoke’。
以后添加:
有一个替代谓词构建器,其功能相同,但没有扩展:http : //petemontgomery.wordpress.com/2011/02/10/a-universal- predicatebuilder/