渴望在分页结果中加载多个子集合

时间:2011-03-21 13:25:28

标签: c# nhibernate linq-to-nhibernate

我已经远远超出了我的NHibernate功能,似乎......

我正在尝试加载具有三个子集合的给定实体的Top10,但是NHibernate的Linq实现得到了正确的结果......以加载所有子项的整个表为代价。

public class PartnerDto : BaseDto
{
    private IList<EmailContactDto> _emailContacts;
    private IList<TelephoneNumberDto> _telephoneNumbers;
    private IList<string> _chains;
    public EmailContactDto[] EmailContacts
    {
        get { return _emailContacts.ToArray(); }
        set { _emailContacts = value.ToList(); }
    }
    public TelephoneNumberDto[] TelephoneNumbers
    {
        get { return _telephoneNumbers.ToArray(); }
        set { _telephoneNumbers = value.ToList(); }
    }
    public string[] Chains
    {
        get { return _chains.ToArray(); }
        set { _chains = value.ToList(); }
    }
    //more properties
}

映射:

<class name="PartnerDto" table="[Partner]" schema-action="none" lazy="false" mutable="false">
<id name="Id">
  <generator class="hilo"/>
</id>
<bag name="Chains" table="PartnerChains" access="field.camelcase-underscore" lazy="false" fetch="subselect">
  <key column="PartnerId"/>
  <element column="Chain" type="System.String"/>
</bag>
<bag name="TelephoneNumbers" access="field.camelcase-underscore" lazy="false" fetch="subselect">
  <key column="PartnerId"/>
  <composite-element class="TelephoneNumberDto">
    <property name="Name" not-null="true"/>
    <property name="ClickToDial" not-null="true"/>
    <property name="SMS" not-null="true"/>
    <property name="Index" column="[Index]" not-null="true"/>
  </composite-element>
</bag>
<bag name="EmailContacts" access="field.camelcase-underscore" lazy="false" fetch="subselect">
  <key column="PartnerId"/>
  <composite-element class="EmailContactDto">
    <property name="Name" not-null="true"/>
    <property name="Email" not-null="true"/>
    <property name="NewsLetter" not-null="true"/>
    <property name="Index" column="[Index]" not-null="true"/>
  </composite-element>
</bag>
<!-- other properties -->

当我这样做时:

session.Query<PartnerDto>().Take(10);

我得到了正确的10,但我的sql显示它加载了TelephoneNumber表,EmailContact表和PartnerChains表中的所有行,而不是将其限制为我正在加载的10个合作伙伴。

我错过了什么? (是的,我必须急切地加载它们 - 它们将在查询后立即进行序列化。)

编辑:找到解决方案:

我首先只查询分页查询的Id - 然后我使用这些Id查询完整的对象图。由于Top 10现在位于where子句中 - NHibernate也使用它来过滤集合。是的,它并不完美 - 我总共有两次往返和五次查询,但在这一点上仍然是我最好的选择。

2 个答案:

答案 0 :(得分:1)

使用与您的网页尺寸相同的收藏品上的batch-size,然后移除lazy= "false"

这将使用单个查询来获取每个集合类型。

这是最简单的方法,也是效率最高的方法之一。

当然,在您序列化对象之前,会话必须保持打开状态。

答案 1 :(得分:0)

我认为这个问题与linqtoNH没有关系,但是由于你急切地检索集合这一事实是限制,这会导致单个查询的连接无法排名(“前10名”),因为有不再是来自DB的原始结果集中与记录实体的一对一关系。