2009-10-29 149 views
1

我需要NHibernate的幫助。我使用的是2.1,但也嘗試過3,結果相同。最受讚賞的任何幫助!Nhibernate N + 1查詢問題

當使用NHibernate進行ICriteria查詢時,它執行查詢,然後對於查詢中的每個結果,它執行另一個查詢來選擇一個關聯對象,這已經在初始結果集中返回,因爲我正在使用eager加載。這當然會造成糟糕的表現。用下面的映射文件,是完全按照預期低於NHibernate的生成查詢:

exec sp_executesql N'SELECT top 20 this_.ContactCode as ContactC1_48_1_, this_.IsActive as IsActive48_1_, contact2_.ContactCode as ContactC1_47_0_, contact2_.ContactFullName as ContactF2_47_0_ FROM Clients this_ left outer join Contacts contact2_ on this_.ContactCode=contact2_.ContactCode WHERE this_.ContactCode like @p0 and this_.IsActive = @p1 ORDER BY this_.ContactCode asc',N'@p0 nvarchar(7),@p1 bit',@p0=N'DAL001%',@p1=1 

該查詢返回單個記錄,然而與下面的查詢,它檢索信息的相關聯繫緊隨其後對象,它在初始查詢中已完全返回,當然,在返回多條記錄時,會執行N個添加查詢。這完全出乎意料!

exec sp_executesql N'SELECT contact0_.ContactCode as ContactC1_47_0_, contact0_.ContactFullName as ContactF2_47_0_ FROM Contacts contact0_ WHERE [email protected]',N'@p0 nvarchar(6)',@p0=N'DAL001' 

延遲加載關閉。該代碼的ICriteria如下:

  ICriteria clientsFromContactCodeQuery = session.CreateCriteria<Client>() 
       .Add(Restrictions.Like("ContactCode", id + "%")) 
       .Add(Restrictions.Eq("IsActive", true)) 
       .AddOrder(Order.Asc("ContactCode")) 
       .SetMaxResults(maxResultCount); 

      var clientsFromContactCodeList = clientsFromContactCodeQuery.List(); 

我有一個簡單的NHibernate映射文件:

<class name="Contact" table="Contacts" lazy="false"> 
    <id name="ContactCode"> 
     <generator class="assigned" /> 
    </id> 

    <property name="ContactFullName" /> 
    </class> 

    <class name="Client" table="Clients" lazy="false"> 
    <id name="ContactCode"> 
     <generator class="assigned" /> 
    </id> 

    <property name="IsActive" /> 

    <one-to-one 
      name="Contact" 
      class="Contact" 
      lazy="false" 
      fetch="join" 
    /> 

    </class> 

回答

0

試試你的max_fetch_depth屬性設置爲2或3,如果你沒有。不知道這是否可以與一對一的關係一起工作。

<property name="max_fetch_depth">3</property> 
+0

不,不會改變結果 – Gavin 2009-10-29 23:11:10

2

打開延遲加載,然後使用HQL查詢預取所需的子項。

from Client c 
    left join fetch c.Contact 
where 
    c.ContactCode like :id 
and 
    c.IsActive eq true 

我不知道通過語法爲了把我的頭頂部和HQL可能需要進行調整了一下,但是這是解決方案的核心。

0

最奇怪的是,在嘗試對查詢進行各種更改後,從hql到icriteria格式,沒有任何工作。但是,我注意到一些數據中沒有生成N + 1個查詢。事實證明,聯繫人和客戶端表中的主鍵在末尾有空格,當刪除時,解決了問題!

很奇怪,但感謝您的幫助。