用于选择N + 1的NHibernate QueryOver解决方案

时间:2016-04-14 10:35:55

标签: c# nhibernate nhibernate-mapping queryover

我的多对多xml映射存在问题。最近我使用NHibernate Profiler发现了这个选择N + 1问题。我似乎找不到可行的解决方案,也不知道我的映射是好还是查询相关。

场景:我有一个配置文件,可以有多个预定义的标签。标签可以包含父母和/或孩子。这些标签可用于许多配置文件。我将向您展示我的相关课程和映射。

Account.cs

public class Account
{
    public int Id { get; set; }
    public Profile Profile { get; set; }
}

Profile.cs

public class Profile
{
    public int Id { get; set; }
    public IList<ProfileTag> Tags { get; set; }
}

Profile.hbm.xml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Agrolink.Application.Models" assembly="Agrolink.Application">
<class name="Agrolink.Application.Models.Profile" lazy="false" table="Profiles" >

<id name="Id" column="Id"  >
  <generator class="identity" />
</id>

<bag name="Tags" table="ProfileTags" cascade="all-delete-orphan" inverse="true">
  <key column="IdProfile" not-null="true"/>
  <one-to-many class="Agrolink.Application.Models.ProfileTag"  />
</bag>

</class>
</hibernate-mapping>

ProfileTag.cs​​

public class ProfileTag
{
    public int Id { get; set; }

    public Profile Profile { get; set; }

    public Tag Tag { get; set; }
}

ProfileTag.hbm.xml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Agrolink.Application.Models" assembly="Agrolink.Application">
<class name="Agrolink.Application.Models.ProfileTag" lazy="false" table="ProfileTags" >

<id name="Id" column="Id"  >
  <generator class="identity" />
</id>

<many-to-one name="Profile" class="Agrolink.Application.Models.Profile" column="IdProfile" cascade="save-update" />
<many-to-one name="Tag" class="Agrolink.Application.Models.Tag" column="IdTag" cascade="none" />

</class>
</hibernate-mapping>

Tag.cs​​

public class Tag
{
    public int Id { get; set; }

    public Tag Parent { get; set; }

    public IList<Tag> Children { get; set; }
}

Tag.hbm.xml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Agrolink.Application.Models" assembly="Agrolink.Application">
<class name="Agrolink.Application.Models.Tag" lazy="false" table="Tags">

<id name="Id" column="Id"  >
  <generator class="identity" />
</id>

<property name="Name" column="Name" />
<property name="Type"  type="Agrolink.Application.Models.TagType, Agrolink.Application"  column="IdType" />

<many-to-one name="Parent" class="Agrolink.Application.Models.Tag" column="IdParent" cascade="none" />

<bag name="Children" table="Tags" cascade="all" inverse="true">
  <key column="IdParent" not-null="true"/>
  <one-to-many class="Agrolink.Application.Models.Tag"  />
</bag>

</class>
</hibernate-mapping>

当我查询帐户时,我看到他会单独选择所有标签。我怎么能阻止这个?我尝试过使用JoinAlias,但它没有任何作用。

我的父母/孩子的映射是否正常?

感谢所有帮助! THX

1 个答案:

答案 0 :(得分:4)

在Tag.hbm.xml中将批量大小添加到Bag中。

<bag name="Children" table="Tags" cascade="all" inverse="true" batch-size="25">
  <key column="IdParent" not-null="true"/>
  <one-to-many class="Agrolink.Application.Models.Tag"  />
</bag>