Прежде всего вам может потребоваться выполнить только один запрос к серверу БД с использованием объединения, а не инициализировать коллекцию после заказа, подобного так:
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:
Приведенный выше код заменен на что-то, что действительно работает и сейчас проверяется.
Извините за переименование сущностей и коллекций. Я слегка переименовал их для моего тестового проекта.