Перезагрузите ассоциацию / связанную коллекцию в NHibernate
-
11-09-2019 - |
Вопрос
Если у меня есть объект Order со списком OrderDetails, я могу легко загрузить подробную информацию вместе с заказом, используя NHibernateUtil.Инициализировать (Order.Подробности).Таким образом, очевидно, что NHibernate обладает всей информацией для генерации инструкции sql.Но как мне запросить базу данных только для получения подробной информации (аналогично CreateSourceQuery в Entity Framework) без ручного создания критериев?Есть ли что-то вроде NHibernateUtil.getList(Порядок.Подробности)?
Обновить:Используя ответ Дарина, вот к чему я, наконец, пришел.Это достаточно общий метод, я могу реализовать его в базовом классе entity
Dim entity as EntityBase
Dim queryString = String.Format("select entityAlias.{1} from {0} entityAlias where entityAlias.id = :ID", entity.GetType.Name, collectionPropertyName)
Dim query = Session.CreateQuery(queryString).SetParameter("ID", entity.ID)
Return query.List
Решение
У NHibernate есть встроенный метод, позволяющий делать именно то, о чем, я думаю, вы просите.(ISession.Создать фильтр)
Например, если у вас есть загруженный объект Customer с именем customer, у которого есть коллекция заказов с именем Orders, вы можете загрузить заказы, выполнив это.
var orderQuery = session.CreateFilter(customer.Orders, string.Empty);
var orders = orderQuery.List<Order>();
Это эквивалентно следующему, просто немного чище.
var orderQuery = session.CreateQuery("from orders o where o.Customer.id = :customerId")
.SetParameter("customerId", customer.Id);
var orders = orderQuery.List<Order>();
Если вы хотите отфильтровать коллекцию, предложение hql where может быть передано в качестве второго аргумента ISession.CreateFilter(object, string)
Другие советы
Почему бы просто не загрузить Заказ и не получить доступ к его коллекции сведений?Если бы вы могли просто загрузить коллекцию, вы не смогли бы добавить ее в коллекцию, потому что для связи требуется порядок.
Я думаю, вы неправильно используете NHibernateUtil.Инициализируйте.Его цель - принудительная инициализация коллекции прокси (лениво загруженной) в особых случаях.Нетерпеливая загрузка - это противоположность отложенной загрузке;в этом сценарии коллекция всегда загружалась бы со своим родительским объектом, и не было бы необходимости в прокси.Если у вас уже есть объект Order, то доступ к коллекции Details приведет к его загрузке.Если вы хотите получить нетерпеливую выборку, вы можете установить это в параметрах сопоставления.
Рекомендуемый способ запроса объектов в NHibernate - это использование либо API критериев или HQL.Есть ли у вас какие-либо причины против любого из этих двух подходов?
var details = session.CreateCriteria<OrderDetails>().List<OrderDetails>();
var details = session.CreateQuery("from OrderDetails").List<OrderDetails>();
Обновить:
Если вы хотите загрузить только ассоциацию без загрузки родительского объекта, вы могли бы использовать следующий запрос:
var details = session.CreateQuery(
"select " +
" orderDetail" +
"from " +
" Order order," +
" OrderDetail orderDetail " +
"where " +
" orderDetail in elements(order.Details)"
)
.List<OrderDetail>();