2009-10-09 60 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的列。