【问题标题】:QueryOver API OrderBy using CaseQueryOver API OrderBy 使用案例
【发布时间】:2012-09-14 16:04:29
【问题描述】:

如何使用 QueryOver API 执行以下 LINQ to NHibernate 查询。这会从数据库中获取项目的所有记录的列表,并将状态为“已返回”的项目放在列表的末尾。状态是一个 Enum,它映射到数据库中的 nvarchar。

var workList = session.Query<Item>()
                .OrderBy(i=> i.Status == Status.Returned ? 1 : 0)
                .ToList();

SQL 等价物是

SELECT *
FROM Item
ORDER BY case when Status='Returned' then 1 else 0 end

我当然试过了

var workList = session.QueryOver<Item>()
                .OrderBy(i => i.Status == Status.Returned ? 1 : 0).Asc
                .ToList();

但我得到以下内容

InvalidOperationException:类型的变量“i” 'MyProject.Model.Entities.Item' 从范围''引用,但它是 未定义

在这种情况下,由于某些其他功能存在问题,我无法使用 LINQ。

【问题讨论】:

    标签: nhibernate queryover


    【解决方案1】:

    你应该可以在这里使用Projections.Conditional 代替:

    Item itemAlias = null;
    
    var workList = 
        session.QueryOver<Item>(() => itemAlias)
            .OrderBy(Projections.Conditional(
                Restrictions.Where(() => itemAlias.Status == Status.Returned),
                Projections.Constant(1),
                Projections.Constant(0))).Asc
            .List();
    

    这有点冗长,但应该可以完成工作。

    【讨论】:

    • 虽然 Alias 在这种情况下做了什么,但效果很好?
    • 它只是使您能够引用Restrictions.Where 调用中的表。如果你愿意,你也可以试试Restrictions.Where&lt;Item&gt;(i =&gt; i.Status == Status.Returned),但我用那个版本得到了奇怪的结果。
    • 太棒了。我使用它来对包含一些空字符串的表进行排序。这里没有足够的空间,但基本上,通过 Projections.Conditional 和 ThenBy(x -> x.LastName).Asc 做相反的事情,你就可以参加比赛了。现在可以使用 QueryOver 和 Skip/Take 进行分页。
    • 嗨安德鲁,我面临着类似的情况,用户提供的序列需要实施或订购。使用投影列表时,我按顺序得到“AS”并导致错误。多次使用静态 .Orderby() 时,它可以工作,但在 if() 条件下使用时,SQL 中没有 order by。知道如何实现这一目标吗?
    • 如果我们有多种情况,比如当 Status='Returned' 时有 1 种情况,当 Anotherfield = 1 时有 'this' 情况,当 othertablefield > 2 时有 9 种情况,否则 0 结束
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    相关资源
    最近更新 更多