Как я могу запросить объекты с вложенными свойствами, используя 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:
- 15,4. Ассоциации (цитировать:)
Вы можете легко указать ограничения для связанных объектов, перемещаясь по ассоциациям, используя
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>();
Также проверьте это: