nhibernate: как инициализировать дочерние объекты списка - PullRequest
1 голос
/ 15 мая 2010

У меня есть следующий метод в моем хранилище. Это работает нормально, мои элементы orderItems инициализированы, как и предполагалось, однако orderItems содержит другую коллекцию с именем OrderItemAddress. Они не инициализированы. Как бы я это сделал?

public Model.Order Get(int id)
{
    using (ISession session = NHibernateHelper.OpenSession())
    {
        Model.Order order = session
            .CreateCriteria(typeof(Model.Order))
            .Add(Restrictions.Eq("Id", id))
            .UniqueResult<Model.Order>();

        NHibernateUtil.Initialize(order.OrderItems);
        return order;
    }
}

1 Ответ

5 голосов
/ 15 мая 2010

Прежде всего вам может потребоваться выполнить только один запрос к серверу БД с использованием объединения, а не инициализировать коллекцию после заказа, подобного так:

public Model.Order Get(int id)
{
    using (ISession session = NHibernateHelper.OpenSession())
    {
        Model.Order order = session
            .CreateCriteria(typeof(Model.Order))
            .Add(Restrictions.Eq("Id", id))
            .SetFetchMode("OrderItems", FetchMode.Join)
            .UniqueResult<Model.Order>();

        return order;
    }
}

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

var orderCriteria = DetachedCriteria.For<Order>()
    .SetFetchMode("OrderLines", FetchMode.Eager)
    .Add(Restrictions.Eq("Id", orderId));

var orderLinesCriteria = DetachedCriteria.For<OrderLine>()
    .CreateAlias("Order", "order")
    .SetFetchMode("Addresses", FetchMode.Eager)
    .Add(Restrictions.Eq("order.Id", orderId));

IList list = s.CreateMultiCriteria()
    .Add(orderCriteria)
    .Add(orderLinesCriteria)
    .List();

var order = ((IList)list[0]).Cast<Order>().First();

Это, к сожалению, еще не проверено, я смогу сделать это позже. Идея состоит в том, чтобы сделать мультизапрос, который получает все необходимые сущности за один раз (это может быть не самый эффективный из возможных запросов к базе данных, но это, по крайней мере, только одна поездка), а затем позволить сеансу сшивать фактический граф из двух результатов. наборы.

В моем текущем проекте отлично работает немного другой сценарий использования, но я немного не уверен, что приведенное здесь совершенно правильно. Но я вернусь к этому:)

EDIT: Приведенный выше код заменен на что-то, что действительно работает и сейчас проверяется. Извините за переименование сущностей и коллекций. Я слегка переименовал их для моего тестового проекта.

...