【问题标题】:NHibernate - filtering out results based on child-propertyNHibernate - 根据子属性过滤掉结果
【发布时间】:2011-04-26 12:16:42
【问题描述】:

我有这段代码来获取所有启用的组及其子组。我遇到的问题是孩子也可以被禁用,但我无法流畅地休眠以仅获取启用了 all 孩子的组。我认为这是可能的,但如何?

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();
}

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate queryover


    【解决方案1】:

    您需要使用子查询来实现您想要的。为了做到这一点,您需要添加对 ChildType 实体的 Group 引用。

    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;
    

    这将获取所有未禁用且没有禁用子级的组。

    【讨论】:

    • 组和孩子之间存在 N:M 关系,这使得子查询有点烦人,但如果我解决了这个问题,我想这就是我将使用的解决方案。谢谢!
    • 对于子查询,您只需要使用Select 来进行投影。
    【解决方案2】:
    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/

    【讨论】:

    • 在将 .Where(x => !x.IsDisabled) 更改为 .Where(x => !children.IsDisabled) 之后,我得到了一些工作,但如果 any 的孩子被启用,而不是如果 所有 他们都被启用。
    • @Fredrik - 哦,对不起,我看错了。我认为你必须做一个存在,所以查询所有启用但没有禁用的孩子,返回组,然后在上一个查询中查询组 WithSubquery.Exists。 philliphaydon.com/2011/01/… - 我真的需要睡觉了,因为我明天有工作,我会考虑一下查询的外观和回复。
    • 感谢您的帮助,但我使用了 Vadim 建议的解决方案。
    • @Fredrik - 是的,真棒,他完全按照我昨晚的想法做了,除了不存在,这是有道理的。
    猜你喜欢
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多