List vs Set vs Bag in NHibernate
Asked Answered
I

4

113

What's the difference between a list, set and bag in the NHibernate mapping file? How does each relate to the .NET collections?

Imhoff answered 16/12, 2009 at 17:40 Comment(0)
A
235

NHibernate semantics:

  1. List: Ordered collection of entities, duplicate allowed. Use a .NET IList in code. The index column will need to be mapped in NHibernate.

  2. Set: Unordered collection of unique entities, duplicates not allowed. Use Iesi.Collection.ISet in code (NH prior to v4) or System.Collections.Generic.ISet (NH v4+). It is important to override GetHashCode and Equals to indicate the business definition of duplicate. Can be sorted by defining an orderby or by defining a comparer resulting in a SortedSet result.

  3. Bag: Unordered list of entities, duplicates allowed. Use a .NET ICollection<T> in code. The index column of the list is not mapped and not honored by NHibernate.

Addie answered 17/12, 2009 at 13:15 Comment(3)
Re: #2, can't we use just regular ISet instead of Iesi?Impartial
@SergeyTachenov: see #9222558 for a possible answer. When this answer was written ISet was not a part of .netAddie
The least popular answer to that question is yes, since NHibernate 4. So maybe this question needs to be edited too.Impartial
L
21

All of these objects in NHibernate are exactly the same as other implementations of these Abstract Data Types (ADT). I was surprised how hard it is to find Sets and Bags online because of how common the names are for other things, so I've listed some links and descriptions here.

For more detailed information take a look at the following: Lists, Sets and Bags

The general rules are:

Lists are by default ordered, use these if you want to be able to pull out an object by its index or you have a weird fondness of for loops over foreach loops. You aren't required to access them in order like you would need to in a Linked List. This ADT allows duplicates.

Please note! Although lists are ordered as BryanD mentioned in his answer, there is absolutely nothing saying that it has to be in the order you're expecting from the database when you execute a HQL query unless you specify an order by command. It is because of this that some people like to use Set or Bags instead, so that it doesn't give the illusion of being ordered. Though I say this, most of the time they will appear to be in a visible order, as they are added to the list in the order that they are found in the query that NHibernate runs.

Sets are not by default ordered, you cannot access any variable directly via an index. Sets are by default the only ADT out of the above three which maintain uniqueness of its objects. These are great if you have a collection if you require to not contain duplicates.

Bags (or Multisets) are, as you can see from the links above, a type of Set which does allow the objects within it to be duplicates of other objects. These are not generally used, as Lists ordering can be ignored, and hence treated as a Bag.

In relation to how these are used in NHibernate, nothing is pulled from the database differently depending on which ADT you select here, it is what you want to use it for that should make you choose the different ADT.

Personally, I use Sets for most things as I generally require child objects to be unique and ordering is not an issue. Though I will use Lists where I have an group of objects which I want ordered by something, for instance time, to achieve this order I need to manually set the "order by" in the HQL query.

Lenzi answered 17/12, 2009 at 2:49 Comment(3)
Correction on the List - using a list in a NHibernate mapping file WILL requires mapping an index column. This way the list will be pulled out in the exact order it was put in.Addie
@Michael Gattuso Good point, I should have mentioned in the answer above that I was talking about HQL queries (hence the 'order by' comment) rather than the actual collection specification in your mapping file.Lenzi
One benefit of using bags is that they do not have to be loaded from the database when you add new elements to it. No duplicates to check, no order to determine.Sacker
A
1

Well the primary difference is that lists have an implicit ordering to the elements, indexed by their position in the list. Sets and bags may also be "ordered" usually by a Comparator or an order by clause that is applied when those items come out of the DB. Personally, I've never used Bags ... if I know the data I want is ordered sequentially I use List otherwise I use Set.

Apples answered 16/12, 2009 at 17:50 Comment(0)
T
0

Set not allows you to have repeated elements in it. If you will try to add some new element, it will compare (Equals method is used) each element that is already in collection with the one you adding, and if one retuns true, element won't be added

Tetryl answered 16/12, 2009 at 21:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.