Perché NHibernate pigro carico legato alla sessione?
-
19-09-2019 - |
Domanda
Utilizzando Castello di ActiveRecord, mi sono imbattuto in un problema quando lazy-carico.
I seguenti lavori (ovviamente)
using (new SessionScope())
{
User singleUser = User.FindFirst(...)
UserGroup groups = singleUser.Groups; // Lazy-loading groups.
}
Dato che ho bisogno di modificare i filtri di sessione in un certo contesto (usando intercettori), creo una nuova SessionScope.
using (new SessionScope())
{
User singleUser;
EnableVariousFiltersInThisThread();
using (new SessionScope())
{
singleUser = User.FindFirst(...);
}
DisableVariousFiltersInThisThread();
UserGroup groups = singleUser.Groups; // Lazy-loading groups.
}
L'ultima riga "singleUser.Groups" getta una LazyInitializationException: "Impossibile inizializzare pigramente una collezione di ruolo: Gruppi, nessuna sessione o la sessione è stata chiusa".
Tuttavia, tutte le altre operazioni sessione di lavoro in modo corretto. Così sembra che "monoutente" è legato alla SessionScope ora smaltiti. Perché? E come può essere risolto in alternativa?
Soluzione
Il mio GUESS è - parte della ragione è di circa "Identità Map". Non solo oggetti caricati pigro, ma anche tutti gli oggetti sono destinati a una sessione. In questo modo che non vi siano due oggetti rappresentano una singola riga nel database.
Altri suggerimenti
Credo che questo sia il modo in cui funziona NHibernate.
I tuoi soggetti sono tutti associati con una sessione e di utilizzare per caricamento pigro. Se si smaltisce la sessione, non è possibile recuperare le collezioni caricati pigri e proprietà. La risposta, ovvia considerazione questa limitazione, è quello di evitare lo smaltimento della sessione -. O per mantenere in vita la sessione fino a quando non sono stati estratti i dati necessari
L'ambito interno è diverso da quello esterno; non supporta lazy loading di fuori di questo ambito sia.
È possibile tuttavia ovviare a questa limitazione, se si trucco NHibernate in eager loading entro l'ambito interno. In alternativa, chiamare .ToList()
o simili sulle collezioni si vorrebbe lavorare, prima di uscire dal campo di applicazione ed i dati saranno disponibili anche al di fuori.