2013-10-09 44 views
5

我想選擇一個實體,並獲取相關列表:NHibernate的QueryOver與獲取導致多個SQL查詢和數據庫打

Session.QueryOver<UserRole>() 
      .Fetch(x => x.UsersInRole).Eager 
      .List(); 

導致大量的數據庫訪問的。 第一個是這樣的:

SELECT ... FROM UserRoles 
left outer join UsersInRoles on ... 

,數百單獨的查詢它看起來像:

SELECT ... FROM UsersInRoles 
left outer join UserRoles on ... 
WHERE UserRoles.UserId=? 

的映射如下:

public class UserRoleMap : ClassMap<UserRole> 
{ 
    public UserRoleMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.RoleName); 
     HasManyToMany(x => x.UsersInRole) 
     .Inverse() 
     .LazyLoad() 
     .Table("UsersInRoles"); 
    } 
} 

回答

3

我會說,這種行爲是我們應該期待的。讓我們有一種情況,在我們系統中有2個用戶和2個角色

User1 - Role1 // has only Role1 
User2 - Role1 // now we see that Role2 has more then User1 
User2 - Role2 

比方說,第一查詢,將只檢索用戶1和它的許多一對多的關係role1上。什麼是我們在ISession現在唯一用戶1,所以role1上的用戶集不全(我們不能重複使用裝入的Isession此刻對象)。但是,我們應該怎麼知道我們在哪裏?爲Role1加載的所有數據是否在會話中?

必須發出新查詢,加載數據Role1。而這樣一來,我們就可以在年底有這些疑問的dosens ...

我所看到的最好的解決方案(我在幾乎所有情況下使用它)是batch-size設置:19.1.5. Using batch fetching

HasManyToMany(x => x.UsersInRole) 
    ... 
    .BatchSize(25) 

.BatchSize(25)標記所有收藏地圖,即使是Class地圖也是如此。這將導致多於1個SQL腳本,但是在末尾而不是多於1 +(2-4)取決於批量大小和頁面大小。

+0

嘗試了您的建議。導致1 + 12的查詢 - 之前好多了,但沒有辦法使它少於12? (增加批量大小?) - 批量大小的成本是多少?如果這一切都很好,我會默認設置。 批量大小是唯一的解決方案嗎?沒有可能的連接會導致2個查詢嗎?如果我需要用簡單的SQL編寫自己的自我,我認爲2個查詢就足夠了。謝謝。 –

+1

如果有更好的解決方案比批量大小,也許,我不知道。之所以沒有默認打開,可能是這樣的事實,這是破壞直截了當的邏輯:uninitialize對象的代理是一個驅動程序。它在需要時直接用於數據。批量調整在會話中加入了更多努力來加入這些選擇。無論如何,批量大小在所有*我們的*集合和類映射上。即使在大型場合下,表演也很棒 –