2009-10-09 62 views
1

我有一个查询,我用NHibernate的标准功能编写,我想优化它。该查询加入4个表格。查询工作正常,但生成的SQL返回4个表的所有列,而不仅仅是我想返回的信息。我在查询中使用了SetResultTransformer,它将返回的数据整形为个人,但是直到从服务器返回更大的SQL之后。nhibernate跨表查询优化

这里是NHibernate的标准

 return session.CreateCriteria(typeof(Individual)) 
      .CreateAlias("ExternalIdentifiers", "ExternalIdentifier") 
      .CreateAlias("ExternalIdentifier.ExternalIdentifierType", "ExternalIdentifierType") 
      .CreateAlias("ExternalIdentifierType.DataSource", "Datasource") 
      .Add(Restrictions.Eq("ExternalIdentifier.Text1", ExternalId)) 
      .Add(Restrictions.Eq("ExternalIdentifierType.Code", ExternalIdType)) 
      .Add(Restrictions.Eq("Datasource.Code", DataSourceCode)) 
      .SetResultTransformer(new NHibernate.Transform.RootEntityResultTransformer()); 

和生成的SQL(从NHProfiler)是

SELECT (all columns from all joined tables) 
FROM INDIVIDUAL this_ 
     inner join EXTERNAL_ID externalid1_ 
     on this_.INDIVIDUAL_GUID = externalid1_.GENERIC_GUID 
     inner join EXTERNAL_ID_TYPE externalid2_ 
     on externalid1_.EXTERNAL_ID_TYPE_GUID = externalid2_.EXTERNAL_ID_TYPE_GUID 
     inner join SYSTEM_SRC datasource3_ 
     on externalid2_.SYSTEM_SRC_GUID = datasource3_.SYSTEM_SRC_GUID 
WHERE externalid1_.EXTERNAL_ID_TEXT_1 = 96800 /* @p0 */ 
     and externalid2_.EXTERNAL_ID_TYPE_CODE = 'PATIENT' /* @p1 */ 
     and datasource3_.SYSTEM_SRC_CODE = 'TOUCHPOINT' /* @p2 */ 

我只想从个人表中的列回来。我可以设置投影,但后来我失去了个人类型。

我也可以用DetachedCriteria重写这个。

这些是我唯一的选择吗?

回答

3

我有完全一样的问题,并要求NHibernate的开发团队直接成员之一,这里是我得到了答案:

与标准API,你唯一可以做的就是用一个投影列表并包含根实体的所有属性...然后您将需要使用AliasToBeanResultTransformer。显然不是最佳的解决方案

如果你不介意用hql重写查询,那么你可以很容易地做到这一点。一个hql查询说“从MyEntity e join e.Association”将选择实体列以及关联的列(就像你使用条件的问题一样)。但是一个说“从MyEntity e加入e.Association中选择e”的hql查询只会选择e的列。