2009-04-20 13 views
6

Me llevó mucho tiempo pero finalmente conseguí que Hello World de nHibernate trabajara. Funcionó después de que hice "carga lenta". Honestamente, no podría decirte por qué todo funcionó, pero lo hizo y ahora estoy leyendo que no necesitas una carga floja. ¿Hay un mundo de hola que alguien tiene que es básico para hacer que nHibernate funcione? ¿Tienes que tener una carga floja? Lo pregunto porque me gustaría usar nHibernate pero necesito entender cómo funcionan las cosas.¿Se requiere carga lenta para nHibernate?

Gracias.

¿Conoces un mundo hello que no tenga tantos gastos generales?

¿Es mejor usar carga lenta?

EDIT: Estoy usando asp.net 3.5. Proyecto de aplicación web.

+0

A agregué otra sección en mi respuesta. –

Respuesta

22

No entiendo lo que quieres decir con "Hice carga lenta". La carga diferida es una función, está activada de manera predeterminada y puedes desactivarla si no te gusta.

Hay dos tipos de carga diferida: para referencias a otras entidades y para listas.

Dada esta entidad:

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; } 
} 

Lazy carga en la referencia a usuario

Si tiene carga diferida en el usuario, es necesario definir todos los miembros de la clase de usuario virtual. NHibernate creará un llamado proxy. El proxy es una clase definida en tiempo de ejecución que deriva del usuario. Su código está accediendo a él como Usuario y no sabe que se trata de una subclase. Pero cuando accede a uno de sus miembros la primera vez, las propiedades se cargan desde la base de datos.

Si desea desactivar la carga diferida de la clase de usuario, es necesario hacer esto en su asignación:

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

Entonces NHibernate crea siempre las instancias de usuario tipo, sin proxies. No necesitas tener nada virtual.

Lazy carga en la lista de comentarios

Si utiliza la carga diferida en la lista de comentarios, es la propia lista que implementa la carga diferida. Si accede a la lista la primera vez, se carga desde la base de datos. NHibernate usa una lista que implementa IList, pero no es List.

Si desea desactivar la carga diferida en la lista, esto se hace en el mapeo de Entidad:

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

Por lo general, la carga diferida es una buena cosa, y que la aplicación no tiene que preocuparse por mucho. Pero hay algunos riesgos. Por ejemplo, si serializas una instancia, y es un proxy, obtienes un proxy no inicializado en lugar de algo útil. La carga lenta solo funciona mientras la sesión esté abierta. No siempre es más rápido usar carga lenta. Si necesita cargar todos los datos de todos modos, es más rápido cargarlo de una pieza.

Por lo que la configuración debe hacerse con cuidado.


Editar:

Para responder a su pregunta original: ¿Es la carga diferida requiere para NHibernate? No. Pero: ¿Se requiere carga lenta en mi aplicación? Muy probablemente sí.

Creo que solo las aplicaciones pequeñas y bastante triviales no necesitan una carga lenta. Si tienes un sistema con muchas clases persistentes, necesitarás una carga diferida.

+0

El documento de referencia de NH se contradice por completo con '" Dado que la inicialización diferida puede provocar errores [...], la falta de holgazanería es el valor predeterminado. "' Y '" NHibernate utiliza la recuperación de selección diferida para colecciones y la recuperación de proxy diferida para asociaciones valoradas. "- para colecciones –

+0

@Chris: La primera oración es antigua. Lazy es el predeterminado desde la versión (i-dont-know). La segunda declaración es lo que realmente traté de explicar. –

7

Si está utilizando archivos hbm.xml para su mapeo simplemente agregando un lazy="false" al elemento obtendrá una carga no lenta para todas las propiedades simples. Las entidades extranjeras seguirán siendo perezosas por defecto. Para hacer que deseen agregar lazy="false" al elemento de mapeo. Un beneficio de la carga ansiosa es que ya no necesitará propiedades virtuales en sus clases de entidad.

Edit: Si realmente quiere saber qué está pasando entre bambalinas, NHibernate registra todo usando log4net. Añadiendo

<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> 

dentro <configuration> en su web.config escupirá todo el NHibernate SQL genera el archivo c:\logs\sql.log

Cuestiones relacionadas