为什么NHibernate无法延迟加载,具体取决于SetMaxResults参数?

时间:2010-08-25 13:17:49

标签: c# nhibernate lazy-loading

我们正在尝试在NHibernate中实现一对多关系。这是my colleague's question的改写。

阻止包含 GroupPartnerInterests 的集合,每个 Group 都有公司。以下测试方法使用SetMaxResults(3),但失败并显示SetMaxResults(5)。例外是

  

NHibernate.LazyInitializationException:   初始化[Model.EntityClasses.BaseBlock#100000121437] -failed   懒洋洋地初始化一个集合   角色:   Model.EntityClasses.BaseBlock.GroupPartnerInterests,   没有会议或会议结束。

问题是为什么SetMaxResults的论点很重要?

测试方法是:

[TestMethod]
public void TestGroupPartnerInterests()
{
    using ( ISession session = SessionFactory.OpenSession() )
    {
        IList<Block> blocks = session
            .CreateCriteria( typeof( Block ) )
            .SetMaxResults( 5 ).List<Block>();

        foreach ( var block in blocks )
        {
            TestContext.WriteLine( block.BlockId + " " + block.BlockName );

            if ( block.GroupPartnerInterests != null )
            {
                foreach ( var gpi in block.GroupPartnerInterests )
                {
                    TestContext.WriteLine( gpi.Company.CompanyName );
                }
            }
        }
    }
}

配置XML:

<class name="Block" table="[BLOCK]">
  <id name="BlockId" column="GA_ID" access="field.camelcase-underscore" >
    <generator class="assigned"/>
  </id>
  ... data properties ...
  <many-to-one name="Contract" access="field.camelcase-underscore" 
               fetch="select" unique="true">
    <column name="EPC_ID"/>
  </many-to-one>
  <many-to-one name="Country" access="field.camelcase-underscore" 
               fetch="select" cascade="none">
    <column name="COUNTRY_ID"/>
  </many-to-one>

  <set name="GroupPartnerInterests" access="field.camelcase-underscore"
       cascade="all-delete-orphan" fetch="select">
    <key property-ref="GroupId">
      <column name="PAR_ID"/>
    </key>
    <one-to-many class="GroupPartnerInterest"/>
  </set>
</class>

<class name="GroupPartnerInterest" table="[GROUP_PARTNER_INTERESTS]">
  <composite-id >
    <key-property name="GroupId" column="PAR_ID" />
    <key-property name="CompanyId" column="PU_ID" />
  </composite-id>
  ... data properties ...
  <many-to-one name="Company" access="field.camelcase-underscore" 
               fetch="select" cascade="none">
    <column name="PU_ID"/>
  </many-to-one>
</class>

<class name="Company" table="[COMPANY]">
  <id name="CompanyId" column="PU_ID" access="field.camelcase-underscore" >
    <generator class="assigned"/>
  </id>
  ... data properties ...
  <set name="GroupPartnerInterests" access="field.camelcase-underscore" 
       cascade="all-delete-orphan" inverse="true" fetch="select">
    <key>
      <column name="PU_ID"/>
    </key>
    <one-to-many class="GroupPartnerInterest"/>
  </set>
</class>

1 个答案:

答案 0 :(得分:1)

我不确定这是否是您特定情况下的问题,但一般来说,当使用Nhibernate作为discussed here时,不鼓励使用隐式事务。您的数据访问应始终遵循以下模式:

using(var session = sessionFactory.OpenSession()) 
using(var tx = session.BeginTransaction()) 
{ 
    // execute code that uses the session 
    tx.Commit(); 
}