NHibernate和收集计数

我使用NHibernate进行持久化的以下类设置

public class Person { public string Name { get; set; } public IList Subordinates { get; set; } } 

现在说我有一个带有两列的网格,“Name”和“Number of Subordinates”在NHibernate中执行此操作的最佳方式是什么,同时尽可能保留域对象的使用。

谢谢

您可以创建一个DTO类,用于实例报告/概述…此类可能如下所示:

 public class PersonView { public string Name{ get;set; } public int NumberOfSubordinates{get;set;} } 

然后,您创建一个Criteria查询,在您定义的Criteria中,您要检索所有人员。 但是,您可以指定NHibernate不应返回Person对象,而应返回PersonView对象。 为了能够做到这一点,您需要使用投影和AliasToBeanTransformer:

 ICriteria crit = new Criteria(typeof(Person)); crit.SetProjection (Projections.ProjectionList() .Add (Projections.Property("Name"), "Name") .Add (Projections.Count ("Subordinates"), "NumberOfSubordinates"); crit.SetResultTransformer(Transformers.AliasToBean (typeof(PersonView)); 

像上面这样的东西。 (我没有测试你的具体情况)。 然后,你只需要让NHibernate知道PersonView类的存在,只需“导入”这个类即可。 我有一个hbm.xml文件,我导入了所有的DTO类。 这看起来像

    

然后,NHibernate将为您的Criteria生成一个非常类似的查询:

 SELECT p.Name, COUNT(p.Subordinates) FROM Person INNER JOIN Subordinates ON Person.PersonId = Subordinates.PersonID GROUP BY p.Name 

假设您的HBM更正为Person HasMany Subordinates,您可以获取人员,然后调用Subordinates.Count

如果您需要的只是计数,这是一个适度浪费的过程,因为它将完全填充所有Subordinates集合以获得计数。 我认为你最好创建一个接收Person的方法并返回他们的Subordinates计数,并使用HQL来执行实际的计数function。 如果你不能做直接计数function,你可以让每个下属返回一个与Person FK匹配的值,然后在它返回的集合上调用.Length或.Count。 但是我假设HQL应该能够直接为你计算它。