我對我的ORM使用Nhibernate。我有一個「控制」類與ControlDetail有一對多的關係(即一個控件有很多controlDetails)。爲什麼NHibernate非常渴望獲取我的數據
在控制XML配置它具有以下
<bag name="ControlDetails" lazy="true" access="property" order-by="SortOrder asc" cascade="all-delete-orphan"
table="ControlDetail">
<key column="ControlID"/>
<one-to-many class="ControlDetail"/>
</bag>
這樣的,我相信除非另有告訴它會延遲加載控件的controldetails。
我正在運行NHProf來嘗試修復一些我們遇到的性能問題,並且已經在這些類的周圍選擇了N + 1問題。
我們正在使用存儲庫DA層,並試圖查看是否可以在需要時以熱切方式獲取數據並添加此方法。
public T GetById<T>(Int32 id, List<string> fetch) where T : BaseObject
{
T retObj = null;
ISession session = EnsureCurrentSession();
{
ICriteria criteria = session.CreateCriteria(typeof (T));
criteria.SetCacheable(true);
criteria.Add(Expression.Eq("Id", id));
foreach(var toFetch in fetch)
{
criteria.SetFetchMode(toFetch, FetchMode.Eager);
}
retObj = criteria.List<T>().FirstOrDefault();
}
return retObj;
}
*注:我不是的倉庫是如何建立一個迷,但是我來之前的項目,所以我們有這個模式堅持現在它已完成。
我把這種方法,像這樣
public Control GetByIDWithDetail(int controlID)
{
return DataRepository.Instance.GetById<Control>(controlID, new List<string>() {"ControlDetail"});
}
當我調試GetByID方法,並期待在retObj我可以看到ControlDetails列表已填充(雖然奇怪的是我還注意到,而不調用setFetchMode設置正在填充的列表)
即使有此修復程序NHProf標識與下面的行
List<ControlDetail> details = control.ControlDetails.ToList();
什麼exactl一個選擇N + 1問題Ÿ我錯過了,我怎樣才能制止這種N + 1,但仍然在controlDetails列表迭代
編輯:XML CONFIGS看起來像這樣(略編輯來讓更小)
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="DomainObjects" assembly="DomainObjects">
<class name="Control" lazy="false" table="Control" optimistic-lock="version" select-before-update="true" >
<id name="Id" type="int" column="ControlID" access="property">
<generator class="native" />
</id>
<version name="Version" column="Version" />
<property name="AdministrativeControl" column="AdministrativeControl" access="property" not-null="true" />
<property name="Description" column="ControlDescription" access="property" />
<property name="Title" column="Title" access="property" />
<property name="CountOfChildControls" access="property" formula="(select count(*) from Control where Control.ParentControlID = ControlID)" />
<bag name="ControlDetails" lazy="true" access="property" order-by="SortOrder asc" cascade="all-delete-orphan"
table="ControlDetail">
<key column="ControlID" />
<one-to-many class="ControlDetail" />
</bag>
</class>
</hibernate-mapping>
這
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="DomainObjects" assembly="DomainObjects">
<class name="ControlDetail" lazy="false" table="ControlDetail" select-before-update="true" optimistic-lock="version">
<id name="Id" type="int" column="ControlDetailID" access="property">
<generator class="native" />
</id>
<version name="Version" column="Version" />
<property name="Description" column="Description" access="property" not-null="true" />
<property name="Title" column="Title" access="property" />
<many-to-one name="Control" lazy="false" class="Control" column="ControlID" access="property"/>
</class>
</hibernate-mapping>
'Control'最有可能來自您的第一級緩存,但關係正在延遲加載,因爲關係未設置爲與父級緩存。抓取NHProf並查看緩存匹配與查詢。 – Phill
nhprof在查詢緩存命中/未命中/放置計數中顯示0,在二級緩存命中/未命中/放置計數中顯示0,我將如何解決這個問題? –
這是0命中控制和ControlDetail?或者只是ControlDetail? – Phill