2011-04-26 80 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