20

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

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

由于 Flags 枚举,查询应该搜索UsernameWindowsUsername两者

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

2 回答 2

24

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

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

或者:没有它,表达式是Invoked,这会导致 EF 中的异常:

LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”。

后期补充:

有一个替代的谓词构建器可以做同样的事情但没有展开: http: //petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/

于 2013-01-31T09:20:09.543 回答
-1

这应该有帮助..

包含多列查询

似乎表格设计存在根本问题(如果我错了,请纠正我)。数据库中 IdentifierType 的用途是什么?

于 2013-01-31T08:56:31.473 回答