NHibernate - фильтрация результатов на основе дочерних свойств - PullRequest
3 голосов
/ 26 апреля 2011

У меня есть этот код, извлекающий все включенные группы со своими детьми.У меня проблема в том, что дети также могут быть отключены, но я не могу свободно использовать nhibernate, чтобы выбирать только те группы, где включены all childs.Я предполагаю, что это возможно, но как?

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 между детьми и группами.

Ниже приведено решение Iиспользуется:

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

Ответы [ 2 ]

5 голосов
/ 26 апреля 2011

Вам нужно использовать подзапрос, чтобы достичь того, что вы хотите. Однако для этого вам нужно добавить ссылку на группу к сущности 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;

Получат все группы, которые не отключены и не имеют детей-инвалидов.

1 голос
/ 26 апреля 2011
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/

...