我正在从事的项目中有以下问题。系统中的每个事务都分配给给定的用户。所以交易和用户之间存在多对一的关系,如下所示:
public class User
{
public int ID { get; private set; }
public string FirstName { get; set; }
....
}
public class Transaction
{
public int ID { get; private set; }
public User CreatedBy { get; private set; }
...
}
我已经用 NHibernate 映射了这些实体,以便在 Transaction 和 User 类之间存在多对一的映射。User 对象没有交易列表,但 Transaction 具有对创建它的用户的引用。
现在我想查询以检索创建最多事务的用户列表,但我不知道如何使用 NHibernate 获得前 10 个引用最多的用户。
有任何想法吗?我希望能够使用 ICriteria 而不是 HQL 来完成此任务,但如果需要,HQL 也可以。
更新
我尝试了 sirrocco 的建议,查询为...
DetachedCriteria topReferencedUsers = DetatchedCriteria.For(typeof(Transaction))
.SetProjection(Projections.GroupProperty("CreatedBy.Id"))
.SetProjection(Projections.Count("CreatedBy.Id").As("pcount" ))
.AddOrder(Order.Desc("pcount"))
.SetMaxResults(10);
并将其构建为子查询...
GetSession().CreateCriteria(typeof (User))
.Add(Subqueries.PropertyIn("Id", topReferencedUsers))
.List<User>();
但是此子查询不分组,而是返回事务总数,然后将其用作用户查询的 IN 子句。如果我用两个投影添加 ProjectionList(),我会得到我想要的子查询的输出,但它会失败,因为它试图将两列输出运行到 User 查询的 IN 子句中。如何让 NHibernate 同时投影 ID 和计数,但只加入 ID?
更新 (2)
我尝试了 Sirrocco 的 SqlGroupProjection 建议(谢谢 Sirrocco),但结果是空的。首先它给了我一个错误,说它找不到属性 pcount,这意味着我需要删除订单,这意味着它是按某个时间戳排序的,这是行不通的。但即便如此,它仍然只输出用户被引用的次数,而不是加入用户表的用户 ID。有任何想法吗?谢谢。