私は三角形を形成する少し複雑なオブジェクトモデルを持っています。 User
エンティティは、Items
とTaxonomies
のコレクションを持ちます。 Item
にもタクソノミがあります。便宜上、Item
とTaxonomy
はそのオーナーを知り、Taxonomy
はItem
と知りたいと思っていました。図を参照してください。NHibernate - 3つのクラス間の3つの双方向関係がN + 1を与えます
だから、これは3双方向の関係になります。私の問題は、そのようなNHibernateでそれをマップし、与えられたIDを持つユーザーを求めているとき、私はSelect N+1問題を取得しています。
最初にUser
がロードされ、熱心にItems
が読み込まれます。その後、Taxonomies
は、それに接続された熱心に読み込まれたItem
で読み込まれます。これは、期待通りに、マッピングで定義されているとおりです。しかし、Taxonomies
に関連するItems
を読み込むためのN + 1のクエリがあります。
オブジェクトグラフのすべての部分が既にロードされたので、これは冗長です。 User-Item
リレーションシップを一方向(User
)から(期待どおり2つしかありません)単方向にすると、問題は消えますが、その逆の関係を取り除きたくありません。 3つの関係すべてを双方向で最適なフェッチにすることは可能ですか?ここで
私のマッピングの部品です:
public class UserOverride : IAutoMappingOverride<User>
{
public void Override(AutoMapping<User> mapping)
{
mapping.HasMany(x => x.Items).Inverse()
.Not.LazyLoad().Fetch.Join();
mapping.HasMany(x => x.Taxonomies).Inverse()
.LazyLoad().Fetch.Select();
}
}
public class ItemOverride : IAutoMappingOverride<Item>
{
public void Override(AutoMapping<Item> mapping)
{
mapping.References(x => x.Taxonomy); // many-to-one
}
}
public class TaxonomyOverride : IAutoMappingOverride<Taxonomy>
{
public void Override(AutoMapping<Taxonomy> mapping)
{
mapping.HasOne(x => x.Item).PropertyRef(x => x.Taxonomy)
.Not.LazyLoad().Fetch.Join();
}
}
そして、私は、できるだけ簡単な方法で自分のデータベースを照会:マッピングがすべてのクエリに影響しますので
var user = session.Get<User>(1);
私は他のシナリオでは 'User'を使用しません。とにかく、結果は似ています。最初のクエリは必要なものすべてを結合し、2番目は 'Items'を別々に引っ張ります。もう一度' Items'にN + 1があります。 – NOtherDev
テストの前にマッピングからレイジーローディング仕様を削除しましたか? –
OK、クエリとマッピングバージョンの両方で実行されます。とにかく、なぜすべての値が既に分かっているのであれば、 'Taxonomy'の' Items'を読み込むための別のクエリを発行する必要があるのは不思議です... – NOtherDev