Перезагрузить ассоциацию / связанную коллекцию в NHibernate - PullRequest
1 голос
/ 31 октября 2009

Если у меня есть сущность Order со списком OrderDetails, я могу легко загрузить детали вместе с заказом, используя NHibernateUtil.Initialize (Order.Details). Очевидно, что NHibernate обладает всей информацией для генерации оператора SQL. Но как мне запросить в базе данных только подробности (аналогично CreateSourceQuery в Entity Framework), не создавая критерии вручную? Есть ли что-то вроде NHibernateUtil.GetList (Order.Details)?

Обновление: Используя ответ Дарина, это то, что я наконец-то получил. Это достаточно универсально, я могу реализовать его в базовом классе сущности

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

Ответы [ 3 ]

1 голос
/ 31 октября 2009

Почему бы просто не загрузить ордер и получить доступ к его коллекции данных? Если бы вам удалось просто загрузить коллекцию, вы бы не смогли добавить ее в коллекцию, поскольку для отношений требуется Заказ.

Я думаю, что вы неправильно используете NHibernateUtil.Initialize. Его целью является принудительная инициализация коллекции прокси (с отложенной загрузкой) в особых случаях. Стремительная загрузка противоположна ленивой загрузке; в этом случае коллекция всегда будет загружаться с родительским объектом, и прокси-сервер не понадобится. Если у вас уже есть объект Order, доступ к коллекции Details приведет к его загрузке. Если вы хотите активную выборку, вы можете установить это в параметрах отображения.

1 голос
/ 02 ноября 2009

NHibernate имеет встроенный метод, чтобы сделать именно то, что я думаю, вы спрашиваете. (ISession.CreateFilter)

Например, если у вас загружен объект «Клиент» с именем «Клиент», у которого есть коллекция «Заказы» с именем «Заказы», ​​вы можете загрузить заказы следующим образом.

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)

1 голос
/ 31 октября 2009

Рекомендуемый способ запроса объектов в NHibernate заключается в использовании Criteria API или HQL . Есть ли у вас причины против любого из этих двух подходов?

var details = session.CreateCriteria<OrderDetails>().List<OrderDetails>();
var details = session.CreateQuery("from OrderDetails").List<OrderDetails>();

UPDATE:

Если вы хотите загрузить только ассоциацию без загрузки родительского объекта, вы можете использовать следующий запрос:

var details = session.CreateQuery(
        "select " + 
        "  orderDetail" + 
        "from " + 
        "  Order order," + 
        "  OrderDetail orderDetail " + 
        "where " + 
        "  orderDetail in elements(order.Details)"
    )
    .List<OrderDetail>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...