Ленивая загрузка в NHibernate - PullRequest
3 голосов
/ 17 марта 2009

Если к клиенту прикреплено много заказов. Как бы вы лениво загружали список заказов с помощью NHibernate.

Это что-то, что нужно настроить в файле сопоставления? любая помощь или пример были бы великолепны.

Ответы [ 5 ]

7 голосов
/ 17 марта 2009

Крис предлагает, как я это сделаю, однако, если вы хотите сделать это во время выполнения, вы можете установить режим выборки по вашим критериям так, чтобы он был ленивым, например:

criteria.SetFetchMode("Orders", FetchMode.Lazy)
4 голосов
/ 17 марта 2009

Вот хорошая статья:

http://blogs.chayachronicles.com/sonofnun/archive/2007/03/30/230.aspx

Из вышеприведенной статьи:

Самое распространенное - просто пометить класс атрибутом 'lazy = "true" или указать default-lazy = "true" в объявлении сопоставления:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="@core.assembly@"
 default-access="nosetter.camelcase-underscore" default-lazy="true">

Или

<class name="Cei.eMerge.Core.Domain.Contacts.Contact" table="Contact" lazy="true" >
2 голосов
/ 17 марта 2009

Чтобы выполнить отложенную загрузку определенной коллекции сущности, используйте «lazy = true» в отображении коллекции. Например:

<bag name="EmploymentHistory" cascade="all" inverse="true" lazy="true">
  <key column="PersonID" />
  <one-to-many class="MyDomain.EmploymentRecord, MyDomainAssembly" />
</bag>
1 голос
/ 01 апреля 2009

Хотите ли вы, чтобы у объекта Customer было свойство, содержащее все его Заказы? Я думаю, что это может быть довольно большая коллекция.
Я думаю, что вопрос, который вы должны задать себе:
Сколько раз мне действительно нужен прямой доступ к Заказам Клиента?

Возможно, в этом случае вы не хотите иметь двунаправленную ассоциацию? Возможно, вы не хотите иметь коллекцию Orders в своем классе Customer.
Затем я добавлю метод в мой репозиторий заказов со следующей подписью:

IList<Order> GetOrdersForCustomer( Customer c );

Но я не знаю, возможно ли это для вашей ситуации.

1 голос
/ 17 марта 2009

Все ответы здесь верны, но если вы хотите перенести так много ордеров, вы также должны использовать фильтры, чтобы вам не приходилось загружать их все.

Customer customer = session.CreateCriteria(...)
              .SetFetchMode("Orders", FetchMode.Lazy)
              .UniqueResult<Customer>();

Ilist<Order> orders = session.CreateFilter(customer.Orders," WHERE this.OrderDate < ?")
                      .SetDateTime(...).List();
...