2011-12-20 53 views
2

我有這樣的問題,這似乎是常見的,但實際上沒有從SO和谷歌的解決方案爲我工作。左加入,與QueryOver分離和分頁

讓我們考慮這樣的情況(非常相似,我的):

public class User 
    { 
    public int Id; 
    public string Name; 
    //30 other fields; 
    public IList<Role> Roles; 
    } 

    public class Role 
    { 
    public int RoleNumber; 
    public int UserId; 
    } 

1用戶可以有0-很多角色。

我想在gridview的用戶列表上顯示其字段和額外的「角色」列,這將顯示他的所有RoleNumbers(使用中繼器)。爲了獲得這一點,我需要通過其角色獲得不同的用戶列表。

是否可以使用QueryOver創建這樣的查詢?來自互聯網的所有解決方案都表示,我應該創建子查詢,這將Ids,然後第二個查詢將返回Id在子查詢中的用戶。它的工作原理和返回我明顯的列表,但沒有角色,所以NH爲每個用戶生成額外的選擇,以獲得缺少的信息。

我的查詢:無角色

Role roles = null; 
User users = null; 
IQueryOver<User,User> userQuery = ... 
IQueryOver<User,User> distQuery = ... 
distQuery.JoinAlias(f=> f.Roles,() => Roles, JoinType.LeftOuterJoin) 
     .Select(Projections.Distinct(Projections.Id())); 

userQuery.WithSubquery.WhereProperty(g => g.Id).In<User>((QueryOver<User>) distQuery) //and other joins, wheres etc. 

returnes distincted列表

如果我添加第二個加入到角色將返回列表與角色和複製

如果我添加第二個加入到角色和使用

TransformUsing(new DistinctRootEntityResultTransformer()) 

它將返回與用戶相區別的列表,但分頁不起作用,RowCount()將返回不正確的數字。

任何想法我能做些什麼?

回答

3

基本上你所要求的目前不支持NHibernate。你不能急於加載UsersRoles並檢查分頁。

我首先會得到一個分頁的用戶列表(例如25個),然後在需要它們時懶惰加載角色。

Session.QueryOver<User>().Skip(x).Take(25); 

,改變你的映射文件: -

<bag class="Role" Name="Roles" batch-size='25' ...> 
... 
</bag> 

這將發出一個查詢檢索分頁Users的名單,然後發出第二個查詢以獲取用戶的所有角色。這是迄今爲止最高效的方式。

+0

偉大的答案Rippo :)我只想要縮小選擇的數量並優化我們的頁面,這在某些情況下產生了> 200個選擇(其中大部分都是返回空值)。這幾乎就是我們需要的。 – Kostrzak 2011-12-20 16:58:48