2011-08-15 74 views
0

我有實體的「內容」。每個內容都有一個「Placement」屬性。展示位置具有多對多關係寬度「AdType」實體(展示位置具有映射的IList < \ AdType>屬性)。NHibernate 3.1.0.4000 QueryOver SQL優化

我需要加載至少在一個內容和關聯寬度指定的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從Placement表中查詢所有字段。

我的問題是:enyone是否知道如何修改QueryOver方法來強制NHibernate在一個查詢中加載數據?

+0

不加'.Fetch(X => x.Placement )選擇幫助之前的「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

最後一個應調用SetResultTransformer而不是TransformUsing :) –

+0

thx @Jenea。修復 – Firo