动态where子句(OR)在LINQ到实体 [英] Dynamic where clause (OR) in Linq to Entities

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

问题描述

我学会了如何构建一个动态查询使用LINQ的延迟执行。但查询实际使用 WHERE条件的串联。

我怎样才能达到同样的查询,但逻辑或?

由于标志枚举,查询应搜索的用户名 WindowsUsername 的或的两个的:

大众用户的getUser(IdentifierType型,字符串标识符)
{
    使用(VAR上下文= contextFactory.Invoke())
    {
        VAR查询从U =在context.Users选择U;        如果(type.HasFlag(IdentifierType.Username))
            查询= query.Where(U => u.Username ==标识符);        如果(type.HasFlag(IdentifierType.Windows))
            查询= query.Where(U => u.WindowsUsername ==标识符);        返回query.FirstOrDefault();
    }
}


解决方案

通过 LINQKit的 predicateBuilder你可以建立predicates动态的。

  VAR的查询=从u在context.Users选择U;
VAR preD = predicate.False<使用者>();如果(type.HasFlag(IdentifierType.Username))
    preD = pred.Or(U => u.Username ==标识符);如果(type.HasFlag(IdentifierType.Windows))
    preD = pred.Or((U => u.WindowsUsername ==标识符);返回query.Where(pred.Expand())FirstOrDefault();
//或返回query.AsExpandable()式(preD).FirstOrDefault()。

这是什么展开是:


  

实体框架的查询处理管道无法处理调用前pressions,这就是为什么你需要调用AsExpandable查询的第一个对象。通过调用AsExpandable,激活LINQKit的前pression访问者类调用替换前pressions用更简单的构造,实体框架可以理解。


或者:没有它的前pression是调用 D,从而导致异常的EF


  

在LINQ前pression节点类型调用不LINQ支持实体。


后来另外:

还有一个另外的predicate建设者,做相同的,但没有展开:<一href=\"http://petemontgomery.word$p$pss.com/2011/02/10/a-universal-$p$pdicatebuilder/\">http://petemontgomery.word$p$pss.com/2011/02/10/a-universal-$p$pdicatebuilder/

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.

How can I achieve the same query but with an OR logic?

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

This is what the Expand is for:

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.

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

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

Later addition:

There is an alternative predicate builder that does the same but without Expand: http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/

这篇关于动态where子句(OR)在LINQ到实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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