NHibernate - 加载100.000个记录,每个记录带有一个小的延迟加载集合

时间:2011-04-21 13:06:23

标签: c# .net sql-server nhibernate asp.net-mvc-2

我有一个有一个对象的应用程序,例如每个人都有一小部分自定义属性的人。这个集合通过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>

2 个答案:

答案 0 :(得分:1)

如果在同一会话中执行两个查询,对象应该在会话中,NHibernate将在查询数据库之前检查缓存,因此它将从缓存中提取项目。

因此,执行两个查询,一个用于加载100个根对象,另一个用于加载所有子自定义属性对象。

然后你使用根对象。要验证这是否有效,您可以使用SQL Server探查器来监视正在执行的SQL查询。

答案 1 :(得分:1)

为了提高第二次活动的表现,我会推荐两件事。首先,如果可能,我会使用IStatelessSession来获取所有对象。这将绕过任何缓存并提高性能。

最重要的是,您需要修改查询并急切获取属性。这样您就可以在一个查询中获取所有内容。 http://www.nhforge.org/doc/nh/en/index.html#querycriteria-dynamicfetching