Linq to Entities 中的动态 where 子句 (OR)

本文关键字:子句 OR where 动态 to Entities Linq | 更新日期: 2023-09-27 17:56:51

在这里的帖子中,我学习了如何使用 Linq 的延迟执行构建动态查询。但查询实际上是使用 WHERE 条件的 AND 串联。

如何使用 OR 逻辑实现相同的查询?

由于标志枚举,查询应搜索用户名/或Windows用户名

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();
    }
}

Linq to Entities 中的动态 where 子句 (OR)

使用 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的用途:

实体框架的查询处理管道无法处理调用表达式,这就是需要对查询中的第一个对象调用 AsExpandable 的原因。通过调用 AsExpandable,可以激活 LINQKit 的表达式访问者类,该类将调用表达式替换为实体框架可以理解的更简单的构造。

或者:如果没有它,表达式将Invoke d,这会导致 EF 中出现异常:

LINQ 表达式节点类型"调用"在 LINQ to Entities 中不受支持。

后来添加:

有一个替代谓词生成器可以执行相同的操作,但没有 Expand: http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/

这应该有帮助。

包含对多个列的查询

表格设计中似乎也存在一个基本问题(如果我错了,请纠正我)。数据库中标识符类型的用途是什么?