2012-01-17 6 views
1

私は他のエンティティの複数のコレクションを持つエンティティを持っており、理想的には1つのバッチにそれらをロードしたいと思います。以下の例のセットアップ:エンティティのためのFluent NHibernate - 個別にではなくバッチで子プロパティコレクションを照会する

public Entity1 
{ 
    public virtual int Prop1 {get;set;} 
    public virtual string Prop2 {get;set;} 
    public virtual IList<Entity2> Prop3 {get;set;} 
    public virtual IList<Entity3> Prop4 {get;set;} 
} 

public Entity2 
{ 
    public virtual int Prop1 {get;set;} 
    public virtual string Prop2 {get;set;} 
} 

public Entity3 
{ 
    public virtual int Prop1 {get;set;} 
    public virtual string Prop2 {get;set;} 
    public virtual IList<Entity1> Prop3 {get;set;} 
} 

マッピング:

public class Entity1Map : ClassMap<Entity1> 
{ 
    public ClientMap() 
    { 
     Table("Clients"); 
     Id(m => m.Prop1); 
     Map(m => m.Prop2); 
    } 
} 

public class Entity1Map : ClassMap<Entity1> 
{ 
    public Entity1Map() 
    { 
     Table("Entity1Table"); 
     Id(m => m.Prop1); 
     Map(m => m.Prop2); 
     HasMany(m => m.Prop3).KeyColumn("Prop1").LazyLoad().NotFound.Ignore(); 
     HasMany(m => m.Prop4).KeyColumn("Prop1").LazyLoad().NotFound.Ignore(); 
    } 
} 

public class Entity2Map : ClassMap<Entity2> 
{ 
    public Entity2Map() 
    { 
     Table("Entity2Table"); 
     Id(m => m.Prop1); 
     Map(m => m.Prop2); 
    } 
} 

public class Entity3Map : ClassMap<Entity3> 
{ 
    public Entity3Map() 
    { 
     Table("Entity3Table"); 
     Id(m => m.Prop1); 
     Map(m => m.Prop2); 
     HasOne(m => m.Prop3).ForeignKey("Prop1").LazyLoad(); 
    } 
} 

して、データベースを照会して:私は、エンティティ1のためのデータベースを照会するとき、私はのリターンを

var query = session.CreateCriteria<Entity1>() 
       .CreateCriteria("Prop3", "prop3", JoinType.InnerJoin) 
       .Add(Restrictions.Eq(Projections.Property("Prop2"), "Criteria!")) 
       .SetFetchMode("Prop3", FetchMode.Join) 
       .SetFetchMode("Prop4", FetchMode.Join); 

var clients = query.Future<Entity1>().ToList(); 

//Do other things here with eager loaded collections 

を取得しますエンティティ1のコレクション - 私はNHProfを使用している可能性がありますが、エンティティ2/3のそれぞれに対して1つのクエリが作成され、データベースに移動して個別に収集することができます。つまり、10行のent ity 1は多くのクエリの3倍の発砲をします。代わりに、それらのそれぞれの

SELECT * FROM <table> WHERE id = XXX 
SELECT * FROM <table> WHERE id = YYY 
SELECT * FROM <table> WHERE id = ZZZ 

NHibernateのは、非常に多くの、より

SELECT * FROM <table> WHERE id IN (XXX,YYY,ZZZ) 

のようなものを生産し、よってデータベースを照会する必要はありませんやっようにバッチにそこの方法は、イーガーローディングクエリです時間?

ご迷惑をおかけして申し訳ございませんが、詳細が必要な場合はお知らせください。

+0

私はコレクションを取得したプロパティにバッチサイズを追加することで、これを「解決」するために管理している:あなたのクエリはとても鉱山がある混乱であります他の日。プロパティのバッチサイズは、NHibernateがクエリをバッチアップし、上記のようにINステートメントを使用して結合を行います。これは本当の修正であるかどうかを100%確信しているわけではありませんが、同じ状況の人を助けるかもしれません。 –

答えて

0

アイデアは、今後の別のクエリで各結合を行うことです。 - しばらくの間、他の何かに行って、これだけに戻っ

session.CreateCriteria<Entity1>() 
    .CreateCriteria("Prop3", "prop3", JoinType.InnerJoin) 
    .Add(Restrictions.Eq(Projections.Property("Prop2"), "Criteria!")) 
    .Future<Entity1>(); 

session.CreateCriteria<Entity1>() 
    .Add(Restrictions.Eq(Projections.Property("Prop2"), "Criteria!")) 
    .SetFetchMode("Prop2", FetchMode.Join) 
    .Future<Entity1>(); 

var query = session.CreateCriteria<Entity1>() 
    .Add(Restrictions.Eq(Projections.Property("Prop2"), "Criteria!")) 
    .SetFetchMode("Prop4", FetchMode.Join) 
    .Future<Entity1>(); 

var clients = query.ToList(); 
+0

生成された基準が正しいため、クエリ自体は問題ではないようですが、正しいクエリが多すぎるということが起こっただけです。 –

+0

将来の別のクエリで各リレーションを分割しようとしましたか? – mynkow

+0

私はそれらを分割しないようにしましたが、問題の基準が3つの関係のうちの1つにのみ適用されるため、適切に分割できるかどうかはわかりません。私はチャンスと更新を得るときにそれを試してみましょう。 –

関連する問題