C# NHibernate-基于子属性筛选出结果

C# NHibernate-基于子属性筛选出结果,c#,nhibernate,fluent-nhibernate,queryover,C#,Nhibernate,Fluent Nhibernate,Queryover,我有这段代码获取所有启用的组及其子组。我遇到的问题是,孩子们也可以被禁用,但我无法让fluent nhibernate仅获取启用了所有孩子的组。我想这是可能的,但是怎么可能呢 public class Group { public bool IsDisabled { get; set; } public string Description { get; set; } public ICollection<ChildType> Children { get;

我有这段代码获取所有启用的组及其子组。我遇到的问题是,孩子们也可以被禁用,但我无法让fluent 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();
}
公共类组{
公共布尔被禁用{get;set;}
公共字符串说明{get;set;}
公共ICollection子项{get;protected set;}
}
公共类子类型{
公共布尔被禁用{get;set;}
公共字符串说明{get;set;}
}
公共IList搜索(字符串搜索字符串){
IQueryOver query=Session.QueryOver()
.WhereRestrictionOn(x=>x.Description).IsInsensitiveLike(searchString,MatchMode.Start)
.其中(x=>!x.IsDisabled)
.OrderBy(x=>x.Description).Asc
.Fetch(group=>group.Children);
返回查询
.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();
}
公共类组{
公共长Id{get;set;}
公共布尔被禁用{get;set;}
公共字符串说明{get;set;}
公共ICollection子项{get;protected set;}
}
公共类子类型{
公共长Id{get;set;}
公共布尔被禁用{get;set;}
公共字符串说明{get;set;}
公共ICollection组{get;protected set;}
}
公共IList搜索(字符串搜索字符串){
ChildType child=null;
组=空;
组joinedGroup=null;
var notDisabled=Session.QueryOver.Of()
.其中(x=>x.IsDisabled)
.JoinAlias(x=>x.Groups,()=>joinedgroups)
.其中(x=>joinedGroup==group)
.选择(x=>x.Id);
IQueryOver query=Session.QueryOver()
.WhereRestrictionOn(x=>x.Description).IsInsensitiveLike(searchString,MatchMode.Start)
.JoinAlias(x=>x.examicationtypes,()=>child)
.WithSubquery.WhereNotExists(未禁用)
.OrderBy(x=>x.Description).Asc;
返回查询
.Cacheable()
.List();
}
公共IList搜索(字符串搜索字符串){
Children=null;
IQueryOver query=Session.QueryOver()
.WhereRestrictionOn(x=>x.Description).IsInsensitiveLike(searchString,MatchMode.Start)
.其中(x=>!x.IsDisabled)
.JoinAlias(x=>x.Children,()=>Children)
.其中(x=>!x.IsDisabled)
.OrderBy(x=>x.Description).Asc;
返回查询
.Cacheable()
.List();
}
那应该是你想做的

加入别名也将为您获取别名


您需要使用子查询来实现所需的功能。为了做到这一点,您需要向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;
Group=null;
var childCrit=QueryOver.Of()
其中(c=>c.Group==Group)。和(c=>c.IsDisabled)
.选择(c=>c.Id);
var query=Session.QueryOver(()=>group)
.WhereRestrictionOn(x=>x.Description).IsInsensitiveLike(searchString,MatchMode.Start)
.其中(x=>!x.IsDisabled)
.WithSubquery.WhereNotExists(childCrit)
.OrderBy(x=>x.Description).Asc
.Fetch(group=>group.Children);

这将获得所有未禁用且没有禁用子项的组。

更改后。Where(x=>!x.IsDisabled)到。Where(x=>!children.IsDisabled)我让它工作了一些,但如果任何子项都已启用,而不是所有子项都已启用,我将获得这些组。@Fredrik-哦,对不起,我读错了。我认为您必须执行exists,so查询所有启用但没有禁用的子项,返回组,然后在上一个查询中使用subquery.exists查询组。-我真的需要睡觉了,因为我明天有工作,我会考虑一下查询结果,然后再回答。谢谢你的帮助,但我使用了瓦迪姆建议的解决方案。@Fredrik-是的,太棒了,他做了我昨晚想的事情,除了不存在,这是有道理的。组和子查询之间存在N:M关系,这使得子查询有点烦人,但如果我解决了这个问题,我想这就是我将使用的解决方案。非常感谢。对于子查询,您只需要使用
选择
进行投影。
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;