Как я могу запросить объекты с вложенными свойствами, используя NHibernate?

Хорошо, я видел несколько подобных вопросов, но ответы либо смутили меня, либо казались полностью перегруженными, поэтому я хотел бы задать свой вопрос.

У меня есть класс с именем Tree, у которого есть свойство объекта из класса Plot, у которого есть свойство объекта из класса Year, у которого есть свойство объекта из класса Series, у которого есть строковое свойство с именем Id. Это обобщено ниже.

public class Tree {
    public virtual Plot Plot { get; set; }
    // other properties...
}

public class Plot {
    public virtual Year Year { get; set; }
    // other properties...
}

public class Year {
    public virtual Series Series { get; set; }
    // other properties...
}

public class Series {
    public virtual string Id { get; set; }
    // other properties...
}

Каждый из этих классов соответствует таблице базы данных, а свойства соответствуют полям внешнего ключа (например, таблица Trees имеет поле с именем PlotKey, которое ссылается на запись в таблице Plots). Все, что я хочу сделать, это загрузить все деревья из базы данных, соответствующие серии которых имеют идентификатор "Adrian_2012" или "Образец IPED". Я думал, что это будет довольно легко сделать, используя следующий код:

IList<Tree> trees = session.CreateCriteria<Tree>()
                           .Add(Expression.Or(
                               Expression.Eq("Plot.Year.Series.Id", "Adrian_2012")
                               Expression.Eq("Plot.Year.Series.Id", "IPED Sample")
                           ))
                           .List<Tree>();

Но это бросает: "NHibernate.Exceptions.GenericADOException: не удалось выполнить запрос". Я пытался использовать Expression.Disjunction, я пытался использовать псевдонимы, ограничения и SimpleExpressions, и я знаю, что не происходит ничего глупого, как не отображенные свойства или критерии с ошибками. Единственное, что я видел, это может помочь, это функция ISession.QueryOver<>(), но я очень запутан лямбда-выражениями. У кого-нибудь есть решение для меня, которое бы использовало просто простое выражение CreateCriteria<>, подобное приведенному выше?

Заранее спасибо!

1 ответ

Одна не милая сторона Criteria Запросы в том, что мы должны явно определить цепочку ассоциаций. Т.е. мы должны ввести JOIN:

Вы можете легко указать ограничения для связанных объектов, перемещаясь по ассоциациям, используя CreateCriteria(),

Таким образом, чтобы присоединиться, нам нужен такой синтаксис

var trees = session
     .CreateCriteria<Tree>()
     .CreateCriteria("Plot", "p")
     .CreateCriteria("Year", "y")
     .CreateCriteria("Series", "s")
     .Add(Expression.Or(
         Expression.Eq("s.Id", "Adrian_2012")
         Expression.Eq("s.Id", "IPED Sample")
     ))
     .List<Tree>();

Также проверьте это:

Другие вопросы по тегам