Перезагрузите ассоциацию / связанную коллекцию в NHibernate

StackOverflow https://stackoverflow.com/questions/1654213

  •  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>();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top