2008-11-25 83 views
28

我试图在NHibernate中使用Criteria API获得不同的结果。我知道这可以使用HQL,但我更愿意使用Criteria API来做到这一点,因为我的应用程序的其余部分仅使用此方法编写。我found this forum post,但一直未能得到它的工作。使用标准API获取不同的结果集有什么方法吗?使用Criteria API从NHibernate获取不同的结果集?

编辑:在这样做时,我也想排除主键列,这也是一个身份,并获得其余的不同的记录。有没有办法做到这一点?事实上,不同的记录会返回重复项,因为主键对于每一行都是唯一的,但所有其他字段都是相同的。

回答

23

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

session.CreateCriteria(typeof(Product) 
    .Add(...) 
    .SetResultTransformer(new DistinctEntityRootTransformer()) 
+0

好吧,我从来没有这样做过,所以1快速的问题。我有一个主键,这是一个身份字段。我怎样才能从结果集中排除这个字段,以便不同的结果真的不同?我可以澄清,如果没有意义。 – 2008-11-25 19:20:35

+0

我不知道这是否可能。你可以创建一个与其他字段的DTO,并针对该DTO进行查询,但它需要使用hql。 – Juanma 2008-11-26 10:40:01

+0

DistinctEntityRootTransformer来自哪里? VS不会为我解决它。我在某处丢失了一个程序集吗? – BuddyJoe 2009-02-18 21:34:12

86

要执行不同的查询,您可以设置投影关于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>(); 

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

SELECT DISTINCT FirstName, LastName from Person 

请注意,只有您在投影中指定的属性将在结果来填充。

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

-4

我也遇到了非明显数量的项目的问题(我在我的映射文件中使用fetch =“join”)。我使用LINQ的NHibernate的要解决的问题,这是在使用方式如下:

 var suppliers = (from supplier in session.Linq<Supplier>() 
         from product in supplier.Products 
         where product.Category.Name == produtCategoryName 
         select supplier).ToList().Distinct(); 
-1

我们将使用所有的最先进,最强大和令人印象深刻的小手段来处理这个问题......只有当你阅读“再为真棒准备......它有没有关系准则...

CurrentSession() 
    .QueryOver<GoodBadAndUgly> 
    .Where(...) 
    .TransformUsing(Transformers.DistinctRootEntity) 

所以,如果你来这里希望有办法做到这一点,有你避免与标准甚至搞乱虽然你虽然你将完全不得不朝着这个方向去添加'DISTINCT'到你的SQL中...不再搜索