Требуется ли отложенная загрузка для nHibernate?

Это заняло у меня много времени, но я наконец заставил работать Hello World от nHibernate. Это сработало после того, как я сделал "ленивую загрузку". Честно говоря, я не мог сказать вам, почему все это сработало, но это сработало, и теперь я читаю, что вам не нужна ленивая загрузка. Есть ли у кого-нибудь привет мир, который заставляет работать nHibernate? У вас должна быть ленивая загрузка? Я спрашиваю, потому что хотел бы использовать nHibernate, но мне нужно понимать, как все работает.

Спасибо.

Вы знаете приветственный мир, в котором не так много накладных расходов?

Лучше использовать ленивую загрузку?

РЕДАКТИРОВАТЬ: я использую asp.net 3.5. Проект веб-приложения.


person johnny    schedule 20.04.2009    source источник
comment
В мой ответ добавлен еще один раздел.   -  person Stefan Steinegger    schedule 21.04.2010
comment
< / а>   -  person Rahamath    schedule 26.04.2019


Ответы (2)


Я не понимаю, что вы имеете в виду под «ленивой загрузкой». Ленивая загрузка - это функция, она включена по умолчанию, и вы можете отключить ее, если она вам не нравится.

Есть два вида отложенной загрузки: для ссылок на другие сущности и для списков.

Учитывая эту сущность:

class Entity
{
  // pk
  int id { get; private set; }

  // reference to another entity
  User MyUser { get; set; }

  // list to other entities
  IList<Comments> MyComments { get; set; }
}

Ленивая загрузка ссылки на пользователя

Если у вас есть отложенная загрузка User, вам необходимо определить все члены класса User virtual. NHibernate создаст так называемый прокси. Прокси-сервер - это класс, определенный во время выполнения, который наследуется от пользователя. Ваш код обращается к нему как Пользователь и не знает, что это подкласс. Но когда вы обращаетесь к одному из его членов в первый раз, свойства загружаются из базы данных.

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

<class name="User" lazy="false"> ...

Затем NHibernate всегда создает экземпляры типа User, без прокси. Вам не нужно иметь ничего виртуального.

Ленивая загрузка списка комментариев

Если вы используете отложенную загрузку в списке комментариев, отложенную загрузку реализует сам список. Если вы обращаетесь к списку в первый раз, он загружается из базы данных. NHibernate использует список, реализующий IList, но не List.

Если вы хотите отключить отложенную загрузку в списке, вы делаете это в сопоставлении Entity:

<class name="Entity">
    <bag name="MyComments" lazy="false" >
        ...

Обычно ленивая загрузка - это хорошо, и вашему приложению не нужно об этом заботиться. Но есть риски. Например, если вы сериализуете экземпляр, и это прокси, вы получаете неинициализированный прокси вместо чего-либо полезного. Ленивая загрузка работает только до тех пор, пока сеанс открыт. Не всегда использовать отложенную загрузку быстрее. Если вам все равно нужно загрузить все данные, их быстрее загрузить целиком.

Поэтому настройку нужно делать осторожно.


Изменить:

Чтобы ответить на ваш исходный вопрос: требуется ли для NHibernate ленивая загрузка? Нет. Но: Требуется ли ленивая загрузка в моем приложении? Скорее всего, да.

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

person Stefan Steinegger    schedule 20.04.2009
comment
Справочная документация NH полностью противоречит сама себе с "Since lazy initialization can lead to bugs [...], non-laziness is the default." и "NHibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. - для коллекций - person Chris S; 12.08.2011
comment
@Chris: Первое предложение старое. Ленивый по умолчанию, начиная с версии (я-не-знаю). Второе утверждение - это то, что я на самом деле пытался объяснить. - person Stefan Steinegger; 18.08.2011

Если вы используете файлы hbm.xml для сопоставления, простое добавление lazy="false" к элементу <class> обеспечит неленивую загрузку всех простых свойств. По умолчанию иностранные организации все равно будут ленивы. Чтобы они заинтересовались, добавьте lazy="false" к элементу сопоставления. Одним из преимуществ активной загрузки является то, что вам больше не нужны виртуальные свойства в ваших классах сущностей.

Изменить: если вы действительно хотите узнать, что происходит за кулисами, NHibernate регистрирует все, используя log4net. Добавление

<configSections>
  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  <!-- Rest of config sections here -->
</configSections>
<log4net>
  <appender name="SQLFileAppender" type="log4net.Appender.RollingFileAppender, log4net">
    <param name="File" value="C:\Logs\SQL.log" />
    <param name="AppendToFile" value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
  <logger name="NHibernate.SQL" additivity="false">
    <level value="DEBUG" />
    <appender-ref ref="SQLFileAppender" />
  </logger>
</log4net>

внутри <configuration> в вашем web.config будет выплевывать все, что SQL NHibernate генерирует файл c:\logs\sql.log

person Jeff Mc    schedule 20.04.2009