NHibernateにNHibernateとLinqを使ってNHibernate 3.2を使用しています。私はLinqをNHibernateに使って、子をロードせずにコレクションのすべての孫を熱心にロードしたいと思っています。例えば、私は次のクラスを持っていることを言う:Linq to NHibernate - 熱心な孫の子孫ではなく、子どもではない
各親に対してpublic class Parent
{
public virtual int Id { get; set; }
public virtual IList<Child> Children { get; set; }
}
public class ParentMap : ClassMap<Parent>
{
Id(x => x.Id);
HasManyToMany(x => x.Children).ExtraLazyLoad();
}
public class Child
{
public virtual int Id { get; set; }
public virtual IList<Parent> Parents { get; set; }
public virtual IList<Grandchild> Grandchildren { get; set; }
public virtual ProhibitivelyLargeType ProhibitivelyLargeField { get; set; }
public virtual ProhibitivelyLargeType RarelyUsedLargeField { get; set; }
}
public class ChildMap : ClassMap<Child>
{
Id(x => x.Id);
HasManyToMany(x => x.Parents).ExtraLazyLoad();
HasManyToMany(x => x.Grandchildren).ExtraLazyLoad();
Map(x => x.ProhibitivelyLargeField);
Map(x => x.RarelyUsedField).LazyLoad();
}
public class Grandchild
{
public virtual int Id { get; set; }
public virtual IList<Child> Children { get; set; }
public virtual int Age { get; set; }
}
public class GrandchildMap : ClassMap<Grandchild>
{
Id(x => x.Id);
HasManyToMany(x => x.Children).ExtraLazyLoad();
Map(x => x.Age);
}
が、私はその親の孫のすべての合計を組み合わせ年齢を知りたいです。
Dictionary<Parent, int> grandchildAges = session.Query<Parent>()
.FetchMany(p => p.Children)
.ThenFetchMany(c => c.Grandchildren)
.AsEnumerable()
.ToDictionary(
p => p,
p => p.Children.SelectMany(c => c.Grandchildren).Sum(g => g.Age)
);
この方法で正しい結果が得られます。ただし、すべてのChildオブジェクトをロードする必要があります。子はProhibitivelyLargeTypeという型のフィールドを含んでいますが、これは遅延ロードされていないので、私は本当に子については何もロードしないことを好みます。しかし、FetchMany/ThenFetchManyを使用しないと、N + 1の問題が発生し、それぞれの子どもと孫のデータベースへの移動が行われますが、これも受け入れられません。
また、ProhibitivelyLargeField LazyLoadを作成することもできます。しかし、Childクラスを使用するほとんどのアプリケーションは、ProhibitivelyLargeFieldを使用する必要がありますが、既にLazyLoadであるRarelyUsedLargeFieldをロードする必要はありません。私が理解しているように、1つのLazyLoadプロパティを読み込むと、すべてのLazyLoadプロパティがロードされるため、このソリューションは通常の使用例を駄目にします。
NHibernateにLinqを使用して探している情報を取得する方法があるのですか、またはCriteria Query APIを使用する必要がありますか?
ありがとうございます!
はProhibitivelyLargeField LazyLoadは望ましくない
は、lazyloadedオプションとして 'ProhibitivelyLargeType'を定義していますか? – Firo
@Firoいいえ、ProhibitivelyLargeFieldにlazyloadedすることはできません。 – chris4600
... ...?遅延ロードを無効にする有効な例をまだ1つは見ていません。 –