【问题标题】:Dynamic where clause (OR) in Linq to EntitiesLinq to Entities 中的动态 where 子句 (OR)
【发布时间】:2013-01-15 07:10:03
【问题描述】:

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

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

由于 Flags 枚举,查询应该搜索 UsernameWindowsUsernameboth

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

【问题讨论】:

    标签: c# linq entity-framework linq-to-entities where-clause


    【解决方案1】:

    使用LINQKit's PredicateBuilder 你可以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 可以理解的更简单的构造。

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

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

    后期添加:

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

    【讨论】:

    • 太棒了!完美运行!
    • 是否有不需要第三方库的选项? (我希望避免我公司因使用 3rd 方库而产生的行政麻烦)
    • @Zarepheth 这个“通用谓词构建器”几乎不是第三方库。它是您自己的代码库的一部分。只需在评论中给这个家伙学分:)
    • 我必须在此解决方案中使用 LINQKit 库 - 或点击第二个链接到另一个选项。但是,我继续搜索并安装了满足我需求的Microsoft.Linq.Dynamic NuGet 包。 (微软的免费赠品通常是允许的,无需额外的繁文缛节)。
    • 我应该关注第二个链接;这是一个相对较小的类,我可以复制到我的代码中。哦,好吧,我现在有 Microsoft 软件包。
    【解决方案2】:

    这应该会有所帮助..

    Contains Query on multiple columns

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

    【讨论】:

    • IdentifierType 不是数据库的一部分。它只是告诉函数哪些列应该包含在 WHERE 条件中。
    猜你喜欢
    • 2012-02-25
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多