List vs Set vs Bag dans NHibernate

109

Quelle est la différence entre une liste, un ensemble et un sac dans le fichier de mappage NHibernate? Quel est le lien entre chacun et les collections .NET?

mrblah
la source

Réponses:

230

Sémantique NHibernate:

  1. Liste: collection ordonnée d'entités, duplication autorisée. Utilisez un .NET IListdans le code. La colonne d'index devra être mappée dans NHibernate.

  2. Ensemble: collection non ordonnée d'entités uniques, doublons non autorisés. Utilisation Iesi.Collection.ISeten code (NH avant v4) ou System.Collections.Generic.ISet(NH v4 +). Il est important de remplacer GetHashCodeet Equalsd'indiquer la définition commerciale du doublon. Peut être trié en définissant un ordre par ou en définissant un comparateur aboutissant à un SortedSetrésultat.

  3. Sac: liste non ordonnée d'entités, doublons autorisés. Utilisez un .NET ICollection<T>dans le code. La colonne d'index de la liste n'est pas mappée et n'est pas honorée par NHibernate.

Michael Gattuso
la source
Re: # 2, ne pouvons-nous pas utiliser simplement régulier ISetau lieu de Iesi?
Sergei Tachenov
@SergeyTachenov: voir stackoverflow.com/questions/9222058/… pour une réponse possible. Lorsque cette réponse a été écrite, ISet ne faisait pas partie de .net
Michael Gattuso
La réponse la moins populaire à cette question est oui, depuis NHibernate 4. Alors peut-être que cette question doit également être modifiée.
Sergei Tachenov le
21

Tous ces objets dans NHibernate sont exactement les mêmes que les autres implémentations de ces types de données abstraits (ADT). J'ai été surpris de voir à quel point il est difficile de trouver des ensembles et des sacs en ligne en raison de la fréquence à laquelle les noms sont communs pour d'autres choses, j'ai donc répertorié quelques liens et descriptions ici.

Pour plus d'informations, consultez les éléments suivants: Listes , ensembles et sacs

Les règles générales sont:

Les listes sont ordonnées par défaut, utilisez-les si vous voulez pouvoir extraire un objet par son index ou si vous avez un penchant étrange pour les forboucles sur les foreachboucles. Vous n'êtes pas obligé d'y accéder dans l'ordre comme vous le feriez dans une liste liée . Cet ADT autorise les doublons.

Notez s'il vous plaît! Bien que les listes soient classées comme BryanD l'a mentionné dans sa réponse, rien ne dit qu'elles doivent être dans l'ordre que vous attendez de la base de données lorsque vous exécutez une requête HQL, sauf si vous spécifiez un ordre par commande. C'est à cause de cela que certaines personnes aiment utiliser Set ou Bags à la place, de sorte que cela ne donne pas l'illusion d'être commandé. Bien que je dise cela, la plupart du temps, ils semblent être dans un ordre visible, car ils sont ajoutés à la liste dans l'ordre dans lequel ils se trouvent dans la requête exécutée par NHibernate.

Les ensembles ne sont pas classés par défaut, vous ne pouvez accéder à aucune variable directement via un index. Les ensembles sont par défaut le seul ADT parmi les trois ci-dessus qui maintiennent l'unicité de ses objets . Celles-ci sont parfaites si vous avez une collection si vous souhaitez ne pas contenir de doublons.

Les sacs (ou multisets ) sont, comme vous pouvez le voir à partir des liens ci-dessus, un type d'ensemble qui permet aux objets qu'il contient d'être des doublons d'autres objets. Ceux-ci ne sont généralement pas utilisés, car l'ordre des listes peut être ignoré et donc traité comme un sac.

En ce qui concerne la façon dont ceux-ci sont utilisés dans NHibernate, rien n'est extrait de la base de données différemment selon l'ADT que vous sélectionnez ici, c'est pour cela que vous voulez l'utiliser qui devrait vous faire choisir les différents ADT.

Personnellement, j'utilise des ensembles pour la plupart des choses car j'exige généralement que les objets enfants soient uniques et la commande n'est pas un problème. Bien que j'utilise des listes où j'ai un groupe d'objets que je souhaite ordonner par quelque chose, par exemple le temps, pour atteindre cet ordre, je dois définir manuellement le «ordre par» dans la requête HQL.

Geai
la source
2
Correction sur la liste - l'utilisation d'une liste dans un fichier de mappage NHibernate nécessitera de mapper une colonne d'index. De cette façon, la liste sera tirée dans l'ordre exact où elle a été mise en place.
Michael Gattuso
@Michael Gattuso Bon point, j'aurais dû mentionner dans la réponse ci-dessus que je parlais des requêtes HQL (d'où le commentaire «commander par») plutôt que de la spécification de collection réelle dans votre fichier de mappage.
Jay
L'un des avantages de l'utilisation des sacs est qu'ils n'ont pas à être chargés à partir de la base de données lorsque vous y ajoutez de nouveaux éléments. Aucun doublon à vérifier, aucun ordre à déterminer.
tvaananen
1

Eh bien, la principale différence est que les listes ont un ordre implicite des éléments, indexés par leur position dans la liste. Les ensembles et les sacs peuvent également être «commandés» généralement par un comparateur ou une clause ordre par ordre qui est appliquée lorsque ces articles sortent de la base de données. Personnellement, je n'ai jamais utilisé de Bags ... si je sais que les données que je veux sont classées séquentiellement, j'utilise List sinon j'utilise Set.

BryanD
la source
0

Set not vous permet d'avoir des éléments répétés dedans. Si vous essayez d'ajouter un nouvel élément, il comparera (la méthode Equals est utilisée) chaque élément qui est déjà dans la collection avec celui que vous ajoutez, et si on renvoie true, l'élément ne sera pas ajouté

Sournois
la source