2010-08-05 14 views
5

Attualmente sto utilizzando un approccio basato sugli attributi per inibire la gestione delle sessioni, il che significa che la sessione è aperta per la durata del metodo Action, ma viene chiusa una volta superato il controllo alla vista.Nhibernate/MVC: gestione delle raccolte lazy load in Visualizza

Mi sembra una buona pratica per me, tuttavia sto correndo per problemi con le raccolte pigri caricate. (Ciò è complicato dal fatto che alcune raccolte sembrano caricarsi lentamente anche se hanno impostato Not.LazyLoad() nella mappatura fluente).

come la vedo io, le mie opzioni sono:

  1. cambiare la mia strategia di gestione ISession e mantenere la sessione aperta nel View
  2. fare un uso migliore delle ViewModels (io non sono attualmente usandoli ovunque).
  3. carico Eager tutte le collezioni che causano problemi (forse paging) (problema fluente non sopportare)

1 sembra un po 'sbagliato essere - ma può essere la soluzione 'semplice'. 2 è probabilmente il modo corretto per andare, ma in alcuni casi ViewModels sembra leggermente ridondante, e sono dispiaciuto di introdurre più classi solo per affrontare questo problema. 3 sembra essere un po 'una soluzione sporca.

Cosa ne pensi?

risposta

3

Il modo migliore per gestirlo (secondo me comunque) è introdurre un livello di servizio tra l'interfaccia utente e i repository; Dovrebbe occuparsi di caricare tutto ciò che è necessario alla vista e trasmettere un dto appiattito (e completamente popolato) alla vista.

Spesso, faccio un passo avanti e mappo i dtos restituiti dal livello di servizio per visualizzare i modelli, che spesso devono contenere dati che sono molto specifici della vista e non appropriati per l'inclusione nel dtos proveniente dal tuo livello di servizio . Ricorda, Automapper è tuo amico quando si tratta di situazioni come questa.

L'utilizzo di una sessione sessione-in-vista è ancora perfettamente accettabile, solo che le tue visualizzazioni non invocano il caricamento pigro sui modelli di entità - questa è quasi sempre un'idea orribile.

+0

Grazie DanP. Ho provato a sperimentare con Automapper. Sembra molto promettente, tuttavia, quando eseguo il mapping di una raccolta sulla mia Entity a una raccolta su un ViewModel, sembra ancora attivare il caricamento lento (anche se la vista ha solo accesso al modello della vista). Posso solo supporre che i riferimenti al proxy vengano passati in questo caso. Hai qualche consiglio su come forzare Automapper a copiare attraverso gli oggetti reali dalla collezione (piuttosto che dai proxy)? – UpTheCreek

+0

@UpTheCreek: semplice, usa anche raccolte di DTO. Impara a non mandare MAI qualcosa mappato in NHibernate (ad esempio le tue effettive classi di dominio) dal livello di servizio. Sembra scoraggiante, ma l'automapper lo rende davvero un gioco da ragazzi ... – DanP

+0

Ah sì, è una sorpresa, grazie! – UpTheCreek

1

considera l'utilizzo corrente come un'operazione implicita del database. L'oggetto viene inviato alla vista ma l'oggetto contiene i proxy che, quando vengono toccati, tentano di restituire i dati e ciò richiede un'operazione di database.

Ora,

  1. estendere la vita ISession tra cui la vista, chiama il suo non è sbagliato, fintanto che non si sta facendo base di dati esplicito ...
  2. non voglio saperlo
  3. Questo è in realtà il modo corretto a prescindere dalla sessione EOL: dovresti provare a fare meno query possibili per richiesta e nhibernate ti dà quella capacità tramite caricamento pigro, futures, multihql/criteri ecc.

nota: sebbene sia possibile mappare una raccolta come non pigra, è importante anche In che modo si esegue una query e si ottiene il set di risultati desiderato. per esempio se stai usando HQL usa un join fetch

+0

Grazie per la risposta - le query che non sono caricate in modo avventato sono basate su ICriteria, non su HQL. – UpTheCreek

0

Non penso che ci sia qualcosa di sbagliato nel primo approccio, e sarà il più semplice da implementare.

La sessione per richiesta è un modello di gestione sessione noto per NHibernate.

Problemi correlati