List vs Set vs Bag in NHibernate


109

Qual è la differenza tra un elenco, un set e una borsa nel file di mappatura NHibernate? Come si relaziona ciascuno alle raccolte .NET?

Risposte:


230

Semantica ibernata:

  1. Elenco: raccolta ordinata di entità, duplicati consentiti. Usa un .NET IListnel codice. La colonna dell'indice dovrà essere mappata in NHibernate.

  2. Set: raccolta non ordinata di entità uniche, duplicati non consentiti. Utilizzare Iesi.Collection.ISetnel codice (NH prima della v4) o System.Collections.Generic.ISet(NH v4 +). È importante sovrascrivere GetHashCodee Equalsindicare la definizione aziendale di duplicato. Può essere ordinato definendo un orderby o definendo un comparatore che dia un SortedSetrisultato.

  3. Borsa: elenco di entità non ordinato, duplicati consentiti. Usa un .NET ICollection<T>nel codice. La colonna dell'indice dell'elenco non è mappata e non viene rispettata da NHibernate.


Ri: # 2, non possiamo usare solo normale ISetinvece di Iesi?
Sergei Tachenov

@SergeyTachenov: vedi stackoverflow.com/questions/9222058/... per una possibile risposta. Quando questa risposta è stata scritta ISet non faceva parte di .net
Michael Gattuso

La risposta meno popolare a questa domanda è sì, poiché NHibernate 4. Quindi forse anche questa domanda deve essere modificata.
Sergei Tachenov

21

Tutti questi oggetti in NHibernate sono esattamente gli stessi di altre implementazioni di questi tipi di dati astratti (ADT). Sono rimasto sorpreso di quanto sia difficile trovare set e borse online a causa di quanto siano comuni i nomi per altre cose, quindi ho elencato alcuni link e descrizioni qui.

Per informazioni più dettagliate dai un'occhiata a quanto segue: Liste , Set e Borse

Le regole generali sono:

Gli elenchi sono ordinati per impostazione predefinita, usali se vuoi essere in grado di estrarre un oggetto dal suo indice o hai una strana predilezione per i forloop su foreachloop. Non è necessario accedervi nell'ordine in cui sarebbe necessario in un elenco collegato . Questo ADT consente duplicati.

Notare che! Sebbene le liste siano ordinate come BryanD ha menzionato nella sua risposta, non c'è assolutamente nulla che dica che deve essere nell'ordine che ti aspetti dal database quando esegui una query HQL a meno che non specifichi un ordine tramite comando. È per questo che ad alcune persone piace usare Set o Bags, in modo che non dia l'illusione di essere ordinati. Anche se lo dico, la maggior parte delle volte appariranno in un ordine visibile, poiché vengono aggiunti all'elenco nell'ordine in cui si trovano nella query eseguita da NHibernate.

Gli insiemi non sono ordinati per impostazione predefinita, non è possibile accedere a nessuna variabile direttamente tramite un indice. I set sono per impostazione predefinita l' unico ADT tra i tre precedenti che mantengono l'unicità dei suoi oggetti . Questi sono ottimi se hai una collezione se hai bisogno di non contenere duplicati.

I sacchetti (o Multiset ) sono, come puoi vedere dai link sopra, un tipo di Set che consente agli oggetti al suo interno di essere duplicati di altri oggetti. Questi non sono generalmente usati, poiché l'ordine delle liste può essere ignorato e quindi trattato come un sacchetto.

In relazione a come questi vengono utilizzati in NHibernate, nulla viene estratto dal database in modo diverso a seconda di quale ADT selezioni qui, è ciò per cui vuoi usarlo che dovrebbe farti scegliere il diverso ADT.

Personalmente, utilizzo i set per la maggior parte delle cose poiché generalmente richiedo che gli oggetti figlio siano univoci e l'ordinamento non è un problema. Anche se userò gli elenchi in cui ho un gruppo di oggetti che desidero ordinato in base a qualcosa, ad esempio il tempo, per ottenere questo ordine ho bisogno di impostare manualmente l '"ordine per" nella query HQL.


2
Correzione nell'elenco: l'utilizzo di un elenco in un file di mappatura NHibernate richiede la mappatura di una colonna indice. In questo modo l'elenco verrà estratto nell'ordine esatto in cui è stato inserito.
Michael Gattuso

@Michael Gattuso Buon punto, avrei dovuto menzionare nella risposta sopra che stavo parlando di query HQL (da qui il commento "order by") piuttosto che della specifica di raccolta effettiva nel file di mappatura.
Jay

Un vantaggio dell'utilizzo dei sacchetti è che non è necessario caricarli dal database quando si aggiungono nuovi elementi. Nessun duplicato da controllare, nessun ordine da determinare.
tvaananen

1

Ebbene, la differenza principale è che le liste hanno un ordinamento implicito degli elementi, indicizzato dalla loro posizione nella lista. I set e le borse possono anche essere "ordinati" solitamente da un Comparatore o da una clausola order by applicata quando tali articoli escono dal DB. Personalmente non ho mai usato Borse ... se so che i dati che desidero sono ordinati in sequenza utilizzo List altrimenti utilizzo Set.


0

Set not ti permette di avere elementi ripetuti in esso. Se proverai ad aggiungere un nuovo elemento, confronterà (viene utilizzato il metodo Equals) ogni elemento che è già nella raccolta con quello che stai aggiungendo, e se uno ritorna vero, l'elemento non verrà aggiunto

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.