是否需要延迟加载nHibernate?

时间:2009-04-20 17:13:02

标签: nhibernate lazy-loading

我花了很长时间但是我终于让nHibernate的Hello World工作了。在我做了“延迟加载”后,它工作了。老实说,我不能告诉你为什么一切都有效,但确实如此,现在我正在读你不需要延迟加载。是否有一个你好的世界,任何人都有这个让nHibernate工作的骨干?你有懒加载吗?我问,因为我想使用nHibernate,但我需要了解事情是如何运作的。

谢谢。

你知道一个没有这么多开销的你好世界吗?

使用延迟加载是否更好?

编辑:我使用的是asp.net 3.5。 Web应用程序项目。

2 个答案:

答案 0 :(得分:22)

我不明白你的意思是“我做了懒加载”。延迟加载是一项功能,默认情况下处于启用状态,如果您不喜欢,可以将其关闭。

有两种延迟加载:用于引用其他实体和列表。

鉴于此实体:

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类的所有成员虚拟。 NHibernate将创建一个所谓的代理。代理是在运行时定义的类,它来自User。您的代码以User身份访问它,并且不知道它是子类。但是,当您第一次访问其中一个成员时,将从数据库中加载属性。

如果要关闭User类的延迟加载,则需要在其映射中执行此操作:

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

然后NHibernate总是创建User类型的实例,没有代理。你不需要虚拟任何东西。

在评论列表上加载延迟

如果在注释列表中使用延迟加载,则列表本身会实现延迟加载。如果您第一次访问该列表,则从数据库加载它。 NHibernate使用一个实现IList的列表,但不是List。

如果要关闭列表中的延迟加载,请在实体映射中执行此操作:

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

通常,延迟加载是一件好事,而你的应用程序并不需要太在意它。但是存在一些风险。例如,如果您序列化一个实例,并且它是一个代理,那么您将得到一个未初始化的代理而不是任何有用的代理。延迟加载仅在会话打开时才有效。使用延迟加载并不总是更快。如果您还需要加载所有数据,则将其加载到一个部件中的速度会更快。

因此需要仔细进行配置。


修改

回答你的原始问题:NHibernate需要延迟加载吗?不。但是:我的申请是否需要延迟加载?很可能是的。

我认为,只有小而简单的应用程序不需要延迟加载。如果你的系统有许多持久化类,你需要延迟加载。

答案 1 :(得分:7)

如果您正在使用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>
web.config中的<configuration>内部将吐出所有SQL NHibernate生成文件c:\logs\sql.log