1

多対多のxmlマッピングに問題があります。最近私はNHibernate Profilerを使用しており、このSelect N + 1問題を発見しました。私は実用的な解決策を見つけることができないと私のマッピングが良いか、そのクエリが関連しているかどうかわからない。Select N + 1のNHibernate QueryOverソリューション

シナリオ:複数のタグを事前に定義しているプロファイルがあります。タグには親や子を持つことができます。これらのタグは、多くのプロファイルで使用できます。私はあなたに関連するクラスとマッピングを表示します。

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> 

私がQueryOverアカウントを使用しているとき、すべてのタグを個別に選択しています。どうすればこれを防ぐことができますか?私はJoinAliasを使ってみましたが、違いはありませんでした。

私のマッピングは親/子どもと大丈夫ですか?

すべてのご協力ありがとうございます。 Thx

答えて

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> 
+0

はい、私のお気に入りの解決策です。その機能の詳細については、[この回答](/ a/36070727/1178314)に詳細な説明を書いてあります。 (途中であなた自身の回答を受け入れることができます) –