我已经远远超出了我的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也使用它来过滤集合。是的,它并不完美 - 我总共有两次往返和五次查询,但在这一点上仍然是我最好的选择。
答案 0 :(得分:1)
使用与您的网页尺寸相同的收藏品上的batch-size
,然后移除lazy= "false"
这将使用单个查询来获取每个集合类型。
这是最简单的方法,也是效率最高的方法之一。
当然,在您序列化对象之前,会话必须保持打开状态。
答案 1 :(得分:0)
我认为这个问题与linqtoNH没有关系,但是由于你急切地检索集合这一事实是限制,这会导致单个查询的连接无法排名(“前10名”),因为有不再是来自DB的原始结果集中与记录实体的一对一关系。