【问题标题】:Fluent NHibernate Querying: OrderBy column of joined table流畅的 NHibernate 查询:连接表的 OrderBy 列
【发布时间】:2014-09-17 08:01:20
【问题描述】:

我一直在努力尝试使用 NHibernate 查询一些东西。 我已经设法进行了一些非常简单的查询,但现在我正在尝试通过 NHibernate 构建一些自定义分页。

我想做的是双重的。 首先 (1),我希望能够根据 连接表中的列 对我的结果集进行排序。 假设我有一个“Person”表,它与“Address”表具有一对一(实际上是多对一)引用。 我想查询“人员”表(使用其字段),但想使用“地址”表中的字段进行排序。

我该怎么做?我尝试了以下两种方式

var resultset = GetCurrentSession().QueryOver<Person>()
                   .Where(x => x.Name == "...")
                   .JoinQueryOver<Address>(x => x.Address)
                   .OrderBy(x => x.HouseNumber).Desc
                   .Skip(...)
                   .Take(...)
                   .List();
// ==> could not execute query

Person person = null;
Address address = null;
var resultset = GetCurrentSession().QueryOver<Person>()
                   .JoinAlias(() => person, () => address.Persons)
                   .Where(() => person.Name == "...")
                   .OrderBy(() => address.HouseNumber).Asc
                   .Skip(...)
                   .Take(...)
                   .List();
// ==> could not resolve property: person of: Person

我的第二 (2) 问题是,我想拆分排序。 基于条件语句,我想添加一个不同的 OrderBy。 我可以就这样吗?

var query = GetCurrentSession().QueryOver<Person>()
               .Where(x => x.Name == "...")
               .JoinQueryOver<Address>(x => x.Address);

if(foo)
{
    query = query.OrderBy(() => address.HouseNumber).Asc
}
else if (bar)
{
    query = query.OrderBy(() => address.Street).Desc
}

var resultset = query                    
                   .Skip(...)
                   .Take(...)
                   .List();

非常感谢!

【问题讨论】:

  • 您能否详细说明第一个异常(“无法执行查询”)?除此之外,感谢您发布一个写得很好的问题

标签: c# pagination fluent-nhibernate sql-order-by queryover


【解决方案1】:

您的所有示例应该都可以工作,但需要注意的是,您需要正确分配别名才能使用它们(消息 could not resolve property: person of: Person 表示 person 从未实际设置为别名)。例如:

Person person = null;
Address address = null;

// Assign the person alias using () => person
var resultset = GetCurrentSession().QueryOver<Person>(() => person)
    .JoinAlias(() => person.Address, () => address) // Assign the address alias here
    .Where(() => person.Name == "...")
    .OrderBy(() => address.HouseNumber).Asc
    .Skip(...)
    .Take(...)
    .List();

这应该可以正常工作。

至于您的第二个问题,您想要实现的目标是非常可能的,这实际上是使用 QueryOver 开始的一个很好的理由。您只需要进行一些调整:

var query = GetCurrentSession().QueryOver<Person>()
               .Where(x => x.Name == "...")
               .JoinQueryOver<Address>(x => x.Address, () => address); // assign address alias

if(foo)
{
    query.OrderBy(() => address.HouseNumber).Asc(); // <-- use the *method* .Asc()
}
else if (bar)
{
    query.OrderBy(() => address.Street).Desc(); // <-- use the *method* .Desc()
}

请注意,由于.Asc().Desc() 实际修改了查询,因此您无需重新分配查询。请务必使用 方法 .Asc().Desc(),以免出现构建错误。

【讨论】:

  • @Andrew Whitaker 假设我们有 .Skip(2) .Take(1),并假设 Person 有 2 个地址,为什么在我的结果中只有 1 个地址?谢谢。
  • @MDDDC:对正在生成的 SQL 进行映像。您将加入Address,然后告诉数据库引擎只采用 first 行。这意味着您只会检索到第一人称 + 地址行。如果您想获取一个人及其所有地址,最好运行两个查询(一个获取该人,另一个获取其所有地址),或者获取该人并让 NHibernate 延迟加载地址。
  • @Andrew Whitaker 嗯,我知道,但老实说,我找不到可以使用此功能的地方。您知道为什么要使用 Fluent Nhibernate 实现分页吗?跨度>
  • @MDDDC:我过去使用 *-to-many 关系的方式是执行我提到的第一个选项——拉回父实体,然后运行另一个查询对于子实体
  • @Andrew Whitaker,我也这样做了。但是为什么没有更好的方法来做到这一点呢?我无法想象为什么仍然没有其他方法。感谢您的 cmets。
【解决方案2】:

这里是动态排序

string orderColumn = "";
            bool isAsc = (param.sSortDir_0 == "asc");
            switch (param.iSortCol_0)
            {
                case 1: orderColumn = "Approved"; break;
                case 2: orderColumn = "CreateDate"; break;
                case 3: orderColumn = "Rate"; break;
            }

            result.UnderlyingCriteria.AddOrder(new NHibernate.Criterion.Order(orderColumn, isAsc));

【讨论】:

    猜你喜欢
    • 2017-10-19
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    • 2011-08-23
    相关资源
    最近更新 更多