2009-04-20 16 views
6

Mi ci è voluto molto tempo, ma alla fine ho potuto far funzionare Hello World di nHibernate. Ha funzionato dopo che ho fatto "caricamento pigro". Onestamente, non potrei dirti perché tutto ha funzionato, ma lo ha fatto e ora sto leggendo non hai bisogno di caricare pigro. C'è un mondo ciao che qualcuno ha che è nudo rendendo il lavoro in ibernato? Devi caricare pigro? Lo chiedo perché vorrei usare nibernate ma ho bisogno di capire come funzionano le cose.È richiesto il caricamento lento per nibernazione?

Grazie.

Conoscete un mondo ciao che non ha un sovraccarico così alto?

È meglio utilizzare il caricamento lazy?

EDIT: Sto usando asp.net 3.5. Progetto di applicazione Web.

+0

A aggiunto un'altra sezione nella mia risposta. –

risposta

22

Non capisco cosa vuoi dire con "Ho fatto carico pigro". Il caricamento lento è una funzione, è attivata per impostazione predefinita e puoi disattivarla se non ti piace.

Esistono due tipi di caricamento lazy: per i riferimenti ad altre entità e per gli elenchi.

Dato questa entità:

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

pigro carico sul riferimento per l'utente

Se si dispone di lazy loading in uso, è necessario definire tutti i membri della classe User virtuale. NHibernate creerà un cosiddetto proxy. Il proxy è una classe definita in fase di esecuzione che deriva dall'utente. Il tuo codice sta accedendo come Utente e non è a conoscenza che è una sottoclasse. Ma quando si accede a uno dei suoi membri la prima volta, le proprietà vengono caricate dal database.

Se si desidera disattivare lazy loading sulla classe utente, è necessario farlo in sua mappatura:

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

Poi NHibernate crea sempre istanze del tipo di utente, senza deleghe. Non è necessario avere qualcosa di virtuale.

pigro carico sulla lista dei commenti

Se si utilizza lazy loading nella lista dei commenti, è la lista stessa che implementa il lazy loading. Se accedi alla lista per la prima volta, viene caricata dal database. NHibernate usa una lista che implementa IList, ma non è una lista.

Se si desidera disattivare il caricamento pigro nella lista, si esegue questa operazione nella mappatura delle Entità:

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

Di solito, lazy loading è una buona cosa, e voi l'applicazione non deve preoccuparsi molto. Ma ci sono alcuni rischi. Ad esempio, se serializzi un'istanza, ed è un proxy, ottieni un proxy non inizializzato invece di qualcosa di utile. Il caricamento lento funziona solo finché la sessione è aperta. Non è sempre più veloce usare il caricamento lazy. Se è necessario caricare comunque tutti i dati, è più veloce caricarlo in un unico pezzo.

Quindi la configurazione deve essere eseguita con attenzione.


Edit:

Per rispondere alla tua domanda iniziale: è lazy loading necessario per NHibernate? No. Ma è richiesto il caricamento lazy nella mia applicazione? Molto probabilmente si.

Penso che solo le applicazioni piccole e piuttosto banali non necessitano di un caricamento lento. Se hai un sistema con molte classi persistenti, avrai bisogno di un caricamento lento.

+0

Il documento di riferimento NH si contraddice completamente con '" Poiché l'inizializzazione pigra può portare a bug [...], la non-pigrizia è l'impostazione predefinita. "' E '" NHibernate utilizza il recupero lazy select per le raccolte e il recupero lazy proxy per single- associazioni di valore. "- per le collezioni –

+0

@Chris: la prima frase è vecchia. Lazy è l'impostazione predefinita dalla versione (i-non-so). La seconda affermazione è ciò che ho effettivamente cercato di spiegare. –

7

Se si utilizzano i file hbm.xml per il mapping semplicemente aggiungendo un lazy="false" all'elemento <class> si otterrà caricamento non-pigro per tutte le proprietà semplici. Le entità straniere saranno ancora pigre per impostazione predefinita. Per renderli desiderosi aggiungi lazy="false" all'elemento di mappatura. Uno dei vantaggi del caricamento ansioso è che non avrai più bisogno di proprietà virtuali sulle tue classi di entità.

Modifica: Se vuoi davvero scoprire cosa succede dietro le quinte, NHibernate registra tutto usando log4net. L'aggiunta di

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

all'interno <configuration> nel web.config sarà sputare tutto il NHibernate SQL genera il file c:\logs\sql.log

Problemi correlati