0

三角形を形成する少し複雑なオブジェクト モデルがあります。とUserのコレクションを持つエンティティがあります。タクソノミーもあります。そして便宜上、私はその所有者を知りたいと思っていました。図を参照してください:ItemsTaxonomiesItemItemTaxonomyTaxonomyItem

ダイアグラム

したがって、これにより 3 つの双方向関係が作成されます。私の問題は、NHibernate でそのようにマップし、指定された ID を持つユーザーを要求すると、Select N+1問題が発生することです。

最初Userは熱心にフェッチされた がロードされますItems。次に、それに接続さTaxonomiesれた熱心にフェッチされてロードされますItem。これは予想どおりであり、マッピングで定義されています。しかし、現在、 にItems関連してロードする N+1 クエリがありますTaxonomies

クエリ

オブジェクト グラフのすべての部分が既に読み込まれているため、これは冗長です。この問題は、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);
4

1 に答える 1

1

マッピングはすべてのクエリに影響するため、エンティティが他のエンティティなしでは決して役に立たない場合にのみ、マッピングを変更して熱心にロードする必要があるというルールに従うのが好きです。あなたの状況では、ユーザーが欲しいだけで、アイテムと分類法のレコードをあまり気にしない場合は、何の利益もなく追加のデータベース作業を行うことになります。

クエリでは、他のルートを介して積極的な読み込みを実行することをお勧めします。

Session.QueryOver<User>().Where(u => u.Id == 1)
    .join.QueryOver<Items>(u => u.Items)
    .Join.QueryOver<Taxonomy>(i => i.Taxonomy)
    .TransformUsing(Trasnformers.DistinctRootEntity);
于 2011-07-11T12:35:20.787 に答える