Linq to Entities 中的动态 where 子句 (OR) [英] Dynamic where clause (OR) in Linq to Entities

查看:33
本文介绍了Linq to Entities 中的动态 where 子句 (OR)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在帖子这里中,我学会了如何构建动态使用 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 逻辑实现相同的查询?

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

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

推荐答案

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

这就是 Expand 的用途:

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

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.

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

Or: without it an expression is Invoked, which causes an exception in EF:

LINQ to Entities 不支持 LINQ 表达式节点类型Invoke".

The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.

后期补充:

有一个替代的谓词构建器,它的功能相同但没有扩展: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 to Entities 中的动态 where 子句 (OR)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆