使用Criteria API从NHibernate获取不同的结果集?

Mar*_*ski 29 nhibernate

我正在尝试使用NHibernate中的Criteria API获得不同的结果.我知道这可以使用HQL,但我更喜欢使用Criteria API来实现这一点,因为我的应用程序的其余部分仅使用此方法编写.我发现这个论坛帖子,但一直无法让它发挥作用.有没有办法使用条件API来获得不同的结果集?

编辑:在执行此操作时,我还想排除主键列,它也是一个标识,并获取剩余的不同记录.有没有办法做到这一点?实际上,不同的记录返回重复项,因为主键对于每一行都是唯一的,但所有其他字段都是相同的.

Aid*_*yle 89

要执行不同的查询,您可以将标准上的投影设置为Projections.Distinct.然后,您可以包含要返回的列.然后通过将结果转换器设置为AliasToBeanResultTransformer,将结果转回强类型对象 - 传入应转换为结果的类型.在此示例中,我使用与实体本身相同的类型,但您可以专门为此查询创建另一个类.

ICriteria criteria = session.CreateCriteria(typeof(Person));
criteria.SetProjection(
    Projections.Distinct(Projections.ProjectionList()
        .Add(Projections.Alias(Projections.Property("FirstName"), "FirstName"))
        .Add(Projections.Alias(Projections.Property("LastName"), "LastName"))));

criteria.SetResultTransformer(
    new NHibernate.Transform.AliasToBeanResultTransformer(typeof(Person)));

IList<Person> people = criteria.List<Person>();
Run Code Online (Sandbox Code Playgroud)

这创建类似于(至少在SQL Server中)的SQL:

SELECT DISTINCT FirstName, LastName from Person
Run Code Online (Sandbox Code Playgroud)

请注意,只会在结果中填充您在投影中指定的属性.

此方法的优点是过滤在数据库中执行,而不是将所有结果返回给您的应用程序,然后进行过滤 - 这是DistinctRootEntityTransformer的行为.


Jua*_*nma 25

此刻无法看到论坛帖子(断开链接?),所以也许这不是答案,但你可以添加一个DistinctRootEntityResultTransformer:

session.CreateCriteria(typeof(Product)
    .Add(...)
    .SetResultTransformer(new DistinctEntityRootTransformer())
Run Code Online (Sandbox Code Playgroud)

  • 了解这会导致数据的客户端转换非常重要.与HQL等价物不同,所有数据 - 无论是否相同 - 都返回给NHibernate.然后NHibernate对该数据进行客户端转换,仅产生不同的实体.这可能比HQL或使用投影效率低得多. (24认同)
  • 在较新版本的NHibernate中,您可以使用Transformers.DistinctRootEntity(它是一个静态属性) (7认同)
  • @Aydan boile的答案更好 - 它执行一个独特的查询. (2认同)

Jon*_*ams 6

对于它的价值,NHibernate:使用Projections优化查询帮助我基本上同样的问题.