在 NHibernate 的 QueryOver API 中为使用连接和投影的查询实现排序和分页的问题

Problems implementing ordering and paging in NHibernate's QueryOver API for queries using joins and projections

我仍在尝试掌握 NHibernate 的窍门。我正在用投影做一些查询,到目前为止我设法想出了这个:

var restrictions = Restrictions.Conjunction();
// add some restrictions

var qo = Session.QueryOver(() => tenantAlias)
    .JoinAlias(x => x.Customer, () => customerAlias)
    .Where(restrictions)                
    .SelectList(list => list
        .Select(() => tenantAlias.Id).WithAlias(() => item.TenantId)
        .Select(() => tenantAlias.DomainName.Value).WithAlias(() => item.DomainName)
        .Select(() => customerAlias.Code.Value).WithAlias(() => item.CustomerCode)
        .Select(() => customerAlias.DisplayName).WithAlias(() => item.CustomerName)
        .Select(() => tenantAlias.ActivationPeriod.From).WithAlias(() => item.ActivationPeriodFrom)
        .Select(() => tenantAlias.ActivationPeriod.Until).WithAlias(() => item.ActivationPeriodUntil)
        .Select(() => tenantAlias.PurchasedLicenses.Value).WithAlias(() => item.PurchasedLicenses)
    )
    .TransformUsing(Transformers.AliasToBean<TenantQueryResult.Item>());

    var items = await qo.ListAsync<TenantQueryResult.Item>();

按照DDD的方式,Tenant是一个聚合根,Customer是一个实体,他们是一对一的关系。到目前为止,此查询运行良好。

但是,现在我想按客户的显示名称属性 订购结果集。我发现有一个 OrderBy 方法,所以我认为添加以下行很简单:

.OrderBy(() => customerAlias.DisplayName)

但是,唉,这不能编译。原因是查询总是 returns IQueryOver<T, T> 的实例,但 OrderBy 子句 returns IQueryOver<T> 而已。 IQueryOver<T> 没有 SelectListTransformUsing 甚至 ListAsync 方法。所以我不明白 OrderBy 子句应该如何工作。 NHibernate 文档 [1] 没有提供示例,谷歌搜索只为我提供了关于 Cats 的简单示例,但从未提供关于连接、转换或投影的示例。

当我尝试向我的查询添加分页时,同样的事情发生了。 Take 和 Skip 方法都可以,但是他们有同样的问题,都是 return IQueryOver<T> 而不是 IQueryOver<T, T>.

那么问题是,在使用连接和投影时,我应该如何使用 QueryOver API 添加排序和分页子句?提前致谢。

[1] http://nhibernate.info/doc/nhibernate-reference/queryqueryover.html

我们必须添加方向 ASC 或 DESC。所以而不是这个

.OrderBy(() => customerAlias.DisplayName)
.TransformUsing(Transformers.AliasToBean<TenantQueryResult.Item>());

我们必须添加 .Asc.Desc

.OrderBy(() => customerAlias.DisplayName)
    .Asc
.TransformUsing(Transformers.AliasToBean<TenantQueryResult.Item>());