2012-08-01 15 views
7

Confesso che non lo sono completamente grok * Ibernazione.Quando dovremmo scegliere nHibernate su altri ORM?

Poiché i micro ORM come Dapper possono essere utilizzati per soddisfare la maggior parte delle esigenze di accesso ai dati, quali sono gli scenari che richiedono una grande arma come nHibernate? Quali sono alcuni esempi di situazioni in cui nibernare risplenderebbe? Per essere chiari, non considero "la possibilità di cambiare il database senza modificare il codice" troppo di un vantaggio. In otto anni di programmazione non ho mai dovuto farlo, e mi sembra un'idea sprecata di tempo per cominciare.

Sono aperto a qualsiasi risposta premurosa ma qui ci sono alcuni esempi di domande che hanno:

  1. Quando è l'API di query vale il lavoro supplementare è necessario mettere in mappatura, rispetto a qualcosa come Dapper?
  2. Come si può sfruttare il carico pigro in un modo che limita lo sforzo di sviluppo e funziona solo?
  3. Quando vale la pena dedicare del tempo alle istruzioni batch?
  4. In quale scenario il sistema di cache è migliore rispetto, ad esempio, alla cache di output delle pagine? È vero solo in ambienti non distribuiti?
  5. Com'è possibile che un semplice mortale come me capisca come funziona ibernato in un ambiente distribuito? Prendi in considerazione il mix di sessioni di cache, batch e stateless e pensa a come i server web con bilanciamento del carico si occuperebbero di tutto ciò.

risposta

6

Wow, grande domanda. Non sono sicuro che un semplice mortale possa rispondere. Ma penso che tu sia troppo veloce per respingere "la possibilità di cambiare il tuo database". Esistono molti pacchetti software, sia commerciali che open source, che offrono la possibilità di lavorare con diversi RDBMS come backing store. Gestire l'SQL per la distribuzione su 2+ piattaforme di database può diventare un incubo assoluto, quindi avere qualcosa che costruisca il tuo SQL in modo prevedibile (almeno rispetto a farlo scrivere a mano) è un enorme vantaggio. Proprio come sostenitore del diavolo, per alcune piattaforme di database ho potuto vedere una crescita del throughput delle transazioni rendendo una scelta di database proibitivamente costosa. La maggior parte degli ORM ti aiuterà in questo modo in un modo o nell'altro, anche se l'API di una query avanzata può fare molto quando le esigenze del database sono sufficientemente complesse.

La risposta breve è che quando il database ha bisogno di un'applicazione per raggiungere un certo livello di complessità, il costo per soddisfare i requisiti non è inferiore al costo della curva di apprendimento di nhibernate. Non posso offrire risposte complete, ma cercherò di esprimere le mie opinioni sugli articoli della lista.

  1. Quando si sta facendo più di un semplice CRUD. L'esigenza di query complesse su più piattaforme di database è probabilmente un buon esempio. Su questo tipo di app si può quasi finire per mantenere due codebase separati (beh, diventano davvero distaccati se si va sul percorso proc memorizzato) e ci può essere un valore nel mantenere tutto il codice in .net (è bello essere in grado di unità prova queste domande con il resto del tuo codice, per esempio).
  2. A parte i problemi riscontrati negli ambienti di media affidabilità, non sono sicuro di cosa sia il caricamento lento che "non funziona" ora. L'unico problema con il caricamento lento nei miei occhi è che devi essere consapevole di ciò per evitare alcuni dei problemi che possono verificarsi quando si prelevano grandi quantità di dati, principalmente il problema di selezione N + 1.
  3. Non è necessario calcolare le istruzioni batch: è sufficiente impostare un valore di configurazione e non pensarci più.Questa è un'enorme ottimizzazione che NHibernate fa per te con il minimo sforzo: il tuo codice può essere molto più pulito quando è direttamente interessato alle operazioni e al controllo delle transazioni.
  4. La memorizzazione nella cache dei dati restituiti può essere utile quando si esegue il rendering delle pagine in modo diverso per utenti diversi o si esegue qualsiasi tipo di elaborazione non banale nel livello del dominio. Anche negli scenari di base, con la cache di output delle pagine potresti finire con la pagina di modifica, la pagina dei dettagli, ecc ... nella cache, mentre nella cache i tuoi dati più vicini all'origine hai solo bisogno di mettere in cache l'entità una volta. La memorizzazione nella cache più vicina alla fonte offre inoltre una maggiore protezione dal servire dati obsoleti. Una cache orientata ai dati può anche essere condivisa su più applicazioni, tramite servizi o puntando nHibernate a un archivio out-of-process come memcached o redis. Questo può essere estremamente prezioso in alcuni ambienti.
  5. Non sono sicuro che tu abbia bisogno di capire come funziona (molte volte uso librerie open-source per proteggermi dal dover capire i dettagli di implementazione di questo genere di cose). Ma la risposta breve è che nessuno di questi si comporta in modo diverso in uno scenario distribuito, ad eccezione del caching (e solo del 2 ° livello di memorizzazione nella cache). Finché utilizzi un provider di cache distribuita (o indirizza tutti i tuoi server allo stesso provider di cache out-of-process), dovresti essere bravo anche su questo fronte.

Sto solo parlando di Ibernare, ma immagino che per Hibernate la storia sia la stessa. Per applicazioni su scala più grande, le applicazioni più complesse possono essere molto vantaggiose, ma c'è un sacco di complessità aggiuntiva che è necessario assumere per trarre questo vantaggio - è ancora probabilmente meno complesso di una soluzione personalizzata per tutti i problemi * Hibernate risolve per te.

Hai anche avuto un sacco di domande sulla memorizzazione nella cache sembra. Suggerisco di leggere oltre this link per avere un'idea di come funzionano le cache di primo e secondo livello. Non cercherò di spiegare qui, perché suona come si sta dopo una comprensione più profonda di quanto io possa inserirsi in questa già lunga risposta :)

5

NHibernate è grande e potente, ma non dovete sapere tutto su di esso avere successo usandolo. Per rispondere alle vostre domande:

  1. Tutte le .NET micro-ORME non hanno alcun supporto LINQ, che io sappia e invece affidamento su di miscelazione stringhe SQL nel codice. Costruire le tue query con LINQ ti offre sicurezza di tipo, controllo in fase di compilazione e grande refactability. Prova a refactoring un codebase con migliaia di query al suo interno se tutte le query utilizzano stringhe SQL ... yikes! E per refactoring, intendo qualcosa di semplice come l'aggiunta di nuove colonne, nuove tabelle, ecc. Che è qualcosa che accade tutto il tempo in un ambiente aziendale. Le stringhe di refactoring sono possibili, diamine è quello che le persone devono ancora fare e che si affidano alle stored procedure, ma di sicuro non sceglierei di farlo se avessi la sicurezza del tipo a mia disposizione.

  2. Con il caricamento lazy, l'unica cosa da tenere a mente è creare uno scenario SELECT N + 1. Ogni volta che il codice esegue un ciclo foreach su un oggetto/entità di dominio, assicurati che la query che popola gli oggetti utilizzi il metodo .Fetch() che crea semplicemente un JOIN in SQL e popola qualsiasi oggetto figlio. Altrimenti, quando si foreach sopra l'oggetto e punto in qualsiasi oggetti figlio, l'ORM dovrà eseguire un'altra istruzione SELECT per "recuperare" i dati. Fondamentalmente, nel gergo di NHibernate, il desiderio è il tuo amico.

  3. Il dosaggio è facile come una torta con NHibernate. Nella configurazione di NHibernate, attiva il batching e il gioco è fatto. Successivamente, se necessario, è possibile regolare la dimensione del batch in fase di esecuzione per query particolari.

  4. Non ho mai utilizzato il caching di secondo livello.Lavoro in un grande ambiente aziendale e le nostre app funzionano molto velocemente senza bisogno di cache. La cache di primo livello in NHibernate però non ha alcuna configurazione necessaria e può semplicemente essere pensata come il rilevamento delle modifiche. Fondamentalmente, internamente NHibernate mantiene un dizionario di quali oggetti ha già recuperato dal database e quali oggetti sono in attesa di essere salvati/aggiornati nel database. Il primo livello di cache è qualcosa a cui non penso mai veramente, ma credo sia bello sapere a un livello rudimentale come funziona.

  5. Ancora una volta, attualmente lavoro in un ambiente aziendale e abbiamo tutti i tipi di applicazioni che utilizzano NHibernate; alcuni piuttosto semplici e altri che utilizzano tutte le potenti funzionalità che NHibernate ha da offrire. Quello che ho visto di solito nella mia esperienza, però, è che non tutti i membri del team devono essere esperti di NHibernate. Tipicamente gli sviluppatori 1 - 3 saranno molto ben informati e tutti gli altri non si preoccuperanno di questo e semplicemente creeranno le loro entità, mappature e continueranno con la loro programmazione. Una volta che l'infrastruttura è a posto e la tua organizzazione ha risolto i modelli che desidera utilizzare, tutto è in genere un gioco da ragazzi.

pensieri supplementari:

Un posto che NHibernate brilla davvero è la sua capacità di mappare qualsiasi tipo di progettazione di database folle che ti buttare a questo. Ora non sto dicendo che sarà facile mappare un pazzo design di database messo insieme nei primi anni '90 in cui si deve unire una procedura memorizzata e un'altra tabella insieme ma è possibile . Ho fatto alcune mappature folli ai miei tempi. Alcuni di quelli che pensavo fossero impossibili perché il database non era progettato per fare ciò che volevamo, ma ogni volta, con persistenza, riesco ancora a farcela con l'incredibile flessibilità di NHibernate nella mappatura del design del database sia buono che cattivo.

Con Micro-ORMS, in genere si finisce con un sacco di stringhe SQL incorporate accanto al codice. Come è considerato pulito ed efficiente. Sembra proprio che tutte le persone stanno facendo sta mettendo quello che usano per mettere in stored procedure nel loro codice ora. In realtà uso i Micro-ORM in alcuni dei miei progetti anche se ha senso, ma in genere quando sto interrogando su una tabella solo per alcuni dati - senza complicate clausole WHERE.

Per essere onesti, io sono una di quelle persone che hanno investito un bel po 'di tempo ad apprendere i dettagli di NHibernate ma non perché avevo bisogno di lavorare, ma perché volevo. Lavoro con un sacco di persone al lavoro che usano NHibernate ogni giorno e non lo capiscono completamente. Ma di nuovo, non ne hanno bisogno. Hai solo bisogno di sapere alcune cose di base e sei a posto.

Spero che questo aiuti.

Problemi correlati