2011-08-15 13 views
0

私はEntity 'Content'を持っています。各コンテンツには「配置」プロパティがあります。プレースメントには、多対多リレーションシップ幅の「AdType」エンティティ(PlacementにはIList <¥AdType>プロパティがマップされています)があります。NHibernate 3.1.0.4000 QueryOver SQL最適化

少なくとも1つのコンテンツと関連する指定されたAdTypeで使用されているすべてのプレースメントを読み込む必要があります。

私のDAL機能は次のようになります。

public IList<Placement> Load(AdType adType) 
    { 
     return NHibernateSession.QueryOver<Content>() 
      .JoinQueryOver(content => content.Placement) 
      .JoinQueryOver<AdType>(placement => placement.AdTypes) 
      .Where(_adType => _adType.Id == adType.Id) 
      .Select(x => x.Placement).List<Placement>(); 
    } 

これは正常に動作しますが、私はSQLログを見ると、私は次を参照してください。

SELECT this_.PlacementId as y0_ FROM AdManager.dbo.[Content] this_ inner join AdManager.dbo.[Placement] placement1_ on this_.PlacementId=placement1_.PlacementId inner join AdManager.dbo.AdTypeToPlacement adtypes5_ on placement1_.PlacementId=adtypes5_.PlacementId inner join AdManager.dbo.[AdType] adtype2_ on adtypes5_.AdTypeId=adtype2_.AdTypeId WHERE adtype2_.AdTypeId = @p0 

SELECT placement0_.PlacementId as Placemen1_26_0_, placement0_.Name as Name26_0_ FROM AdManager.dbo.[Placement] placement0_ WHERE [email protected] 

SELECT placement0_.PlacementId as Placemen1_26_0_, placement0_.Name as Name26_0_ FROM AdManager.dbo.[Placement] placement0_ WHERE [email protected] 

これは、NHibernateのは、最初のクエリですべてのプレースメントIDを取りことを意味次に、プレースメント・テーブルからすべてのフィールドをIDで照会します。

私の質問は次のとおりです:enyoneはQueryOverメソッドを変更してNHibernateのデータを1つのクエリで強制的にロードする方法を知っていますか?

+0

'.Fetch(X => x.Placementを追加し(それはちょうど新しい配置を満たすが、それを追跡するdoest欠点を持っている):あなたは、サブクエリで行くことができます).Eager'を選択してください。 – Firo

+0

番号。ログファイルは同じクエリを表示する=( – Anubis

答えて

0

NHibernateは、プレースメントを初期化するために必要なデータをフィルタリングする場所に何かがあると思われるようです。

public IList<Placement> Load(AdType adType) 
{ 
    var subquery = QueryOver.For<Content>() 
     .JoinQueryOver(content => content.Placement) 
     .JoinQueryOver<AdType>(placement => placement.AdTypes) 
     .Where(_adType => _adType.Id == adType.Id) 
     .Select(x => x.Id); 

    return NHibernateSession.QueryOver<Content>() 
     .WithSubquery.Where(content => content.Id).IsIn(subquery)) 
     //.Fetch(x => x.Placement).Eager try with and without 
     .Select(x => x.Placement).List<Placement>(); 
} 

またはSQLは

public IList<Placement> Load(AdType adType) 
{ 
    return NHibernateSession.CreateSQLQuery("SELECT p.Name as Name, ... FROM content c join placement p...") 
     .SetResultTransformer(Transformers.AliastoBean<Placement>()) 
     .List<Placement>(); 
} 
+0

最後のものは、TransformUsingではなくSetResultTransformerを呼び出す必要があります:) –

+0

thx @Jenea。それを固定した – Firo