2011-04-26 48 views
3

我有這段代碼獲取所有已啓用的組及其子代。我的問題是,孩子們也可以被禁用,但我不能得到流利的nhibernate只獲取全部兒童被啓用的組。我認爲這是可能的,但如何?NHibernate - 根據子屬性篩選出結果

public class Group { 
    public bool IsDisabled { get; set; } 
    public string Description { get; set; } 
    public ICollection<ChildType> Children { get; protected set; } 
} 

public class ChildType { 
    public bool IsDisabled { get; set; } 
    public string Description { get; set; } 
} 

public IList<Group> Search(string searchString) { 
    IQueryOver<Group> query = Session.QueryOver<Group>() 
     .WhereRestrictionOn(x => x.Description).IsInsensitiveLike(searchString, MatchMode.Start) 
     .Where(x => !x.IsDisabled) 
     .OrderBy(x => x.Description).Asc 
     .Fetch(group => group.Children).Eager; 

    return query 
     .Cacheable() 
     .List(); 
} 

編輯:有一個N:兒童和羣體之間的M-關係。

以下是我使用的解決方案:

public class Group { 
    public long Id { get; set; } 
    public bool IsDisabled { get; set; } 
    public string Description { get; set; } 
    public ICollection<ChildType> Children { get; protected set; } 
} 

public class ChildType { 
    public long Id { get; set; } 
    public bool IsDisabled { get; set; } 
    public string Description { get; set; } 
    public ICollection<Group> Groups { get; protected set; } 
} 

public IList<Group> Search(string searchString) { 
    ChildType child = null; 
    Group group = null; 
    Group joinedGroup = null; 

    var notDisabled = Session.QueryOver.Of<ExaminationType>() 
     .Where(x => x.IsDisabled) 
     .JoinAlias(x => x.Groups,() => joinedGroup) 
      .Where(x => joinedGroup == group) 
     .Select(x => x.Id); 

    IQueryOver<Group> query = Session.QueryOver<Group>() 
     .WhereRestrictionOn(x => x.Description).IsInsensitiveLike(searchString, MatchMode.Start) 
     .JoinAlias(x => x.ExaminationTypes,() => child) 
     .WithSubquery.WhereNotExists(notDisabled) 
     .OrderBy(x => x.Description).Asc; 

    return query 
     .Cacheable() 
     .List(); 
} 

回答

5

您需要使用子查詢,以達到你想要的。爲了做到這一點,雖然你需要添加一個Group引用到ChildType實體。

Group group = null; 
var childCrit = QueryOver.Of<ChildType>() 
     .Where(c => c.Group == group).And(c => c.IsDisabled) 
     .Select(c => c.Id); 
var query = Session.QueryOver(() => group) 
     .WhereRestrictionOn(x => x.Description).IsInsensitiveLike(searchString, MatchMode.Start) 
     .Where(x => !x.IsDisabled) 
     .WithSubquery.WhereNotExists(childCrit) 
     .OrderBy(x => x.Description).Asc 
     .Fetch(group => group.Children).Eager; 

這將得到所有沒有被禁用且沒有禁用子項的組。

+0

組和孩子之間存在一個N:M關係,這使得子查詢有點煩人,但如果我解決了這個問題,我想這是我將要使用的解決方案。 謝謝! – 2011-04-26 15:20:10

+0

對於子查詢,您只需使用「選擇」來進行投影。 – Vadim 2011-04-26 16:31:09

1
public IList<Group> Search(string searchString) { 

    Children children = null; 

    IQueryOver<Group> query = Session.QueryOver<Group>() 
     .WhereRestrictionOn(x => x.Description).IsInsensitiveLike(searchString, MatchMode.Start) 
     .Where(x => !x.IsDisabled) 
     .JoinAlias(x => x.Children,() => children) 
      .Where(x => !x.IsDisabled) 
     .OrderBy(x => x.Description).Asc; 

    return query 
     .Cacheable() 
     .List(); 
} 

這應該做你想做的事。

加入別名也會爲您取回。

http://www.philliphaydon.com/2011/04/nhibernate-querying-relationships-are-depth/

+0

改變後 。凡(X =>!x.IsDisabled) 到 。凡(X =>!children.IsDisabled) 我得到了它在一定程度上工作,但我得到的羣體,如果** **任何的兒童可以使用,而不是**所有**都是。 – 2011-04-26 14:36:50

+0

@Fredrik - OH,對不起,我誤讀了。我認爲你必須做一個存在,所以查詢所有啓用沒有禁用的孩子,返回組,然後查詢上一個查詢的組WithSubquery.Exists。 http://www.philliphaydon.com/2011/01/revisiting-exists-in-nhibernate-3-0-and-queryover/ - 我真的需要睡覺因爲我明天有工作,我會考慮如何該查詢將查找並回復。 – Phill 2011-04-26 14:41:29

+0

謝謝你的幫助,但我使用了Vadim建議的解決方案。 – 2011-04-26 17:08:29