Tho*_*fel 18 c# linq linq-to-entities entity-framework where-clause
在这里的帖子中,我学习了如何使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
Ger*_*old 21
使用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();
Run Code Online (Sandbox Code Playgroud)
这就是Expand:
实体框架的查询处理管道无法处理调用表达式,这就是您需要在查询中的第一个对象上调用AsExpandable的原因.通过调用AsExpandable,可以激活LINQKit的表达式访问者类,该类使用Entity Framework可以理解的更简单的结构替换调用表达式.
或者:没有它,表达式为Invoked,这会导致EF中的异常:
LINQ to Entities不支持LINQ表达式节点类型"Invoke".
后来补充:
有一个替代谓词构建器可以执行相同但没有展开:http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/
| 归档时间: |
|
| 查看次数: |
12082 次 |
| 最近记录: |