我有一个有一个对象的应用程序,例如每个人都有一小部分自定义属性的人。这个集合通过nhibernate懒洋洋地加载,9/10次只为一个人加载而不是IList。
这是1/10,虽然我需要导出到数据库中所有人的优秀,我需要包括他们的自定义属性。因此,如果我对此是正确的(并给出下面的映射),nhibernate将针对其自定义属性发出100.000个记录和100.000个查询的1个查询。
有没有办法发出2个查询 - 1个用于记录,1个用于所有自定义属性 - 并且nhibernate是否正确创建了对象?或者只是某种方式来避免这个N + 1问题?
底层数据库是SQL Server 2008,应用程序是ASP.NET MVC应用程序
人物映射是
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> <class name="Core.Person, Core" table="people" optimistic-lock="none">
<id name="ID" column="id" type="System.Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid" />
</id>
<many-to-one name="Company" column="company_id" not-null="true" fetch="join" />
<property name="Name" column="name" type="String" />
<property name="DoB" column="dob" type="DateTime" not-null="true" />
<map name="CustomFields" lazy="true" table="custom_fields" cascade="all-delete-orphan">
<key column="person_id" />
<index column="name" type="System.String" />
<element column="value" type="System.String" />
</map>
</class> </hibernate-mapping>
答案 0 :(得分:1)
如果在同一会话中执行两个查询,对象应该在会话中,NHibernate将在查询数据库之前检查缓存,因此它将从缓存中提取项目。
因此,执行两个查询,一个用于加载100个根对象,另一个用于加载所有子自定义属性对象。
然后你使用根对象。要验证这是否有效,您可以使用SQL Server探查器来监视正在执行的SQL查询。
答案 1 :(得分:1)
为了提高第二次活动的表现,我会推荐两件事。首先,如果可能,我会使用IStatelessSession
来获取所有对象。这将绕过任何缓存并提高性能。
最重要的是,您需要修改查询并急切获取属性。这样您就可以在一个查询中获取所有内容。 http://www.nhforge.org/doc/nh/en/index.html#querycriteria-dynamicfetching