在NHibernate中列出vs Set vs Bag

时间:2009-12-16 17:40:53

标签: nhibernate

NHibernate映射文件中的列表,集合和包之间有什么区别?每个如何与.NET集合相关?

4 个答案:

答案 0 :(得分:219)

NHibernate语义:

  1. 列表:有序的实体集合,允许重复。在代码中使用.NET IList。索引列需要在NHibernate中映射。

  2. 设置:无序的唯一实体集合,不允许重复。在代码中使用Iesi.Collection.ISet(v4之前的NH)或System.Collections.Generic.ISet(NH v4 +)。覆盖GetHashCodeEquals以指示重复的业务定义非常重要。可以通过定义orderby或通过定义导致SortedSet结果的比较器进行排序。

  3. 行李:无序的实体列表,允许重复。在代码中使用.NET ICollection<T>。列表的索引列未映射,也未被NHibernate尊重。

答案 1 :(得分:21)

NHibernate中的所有这些对象与这些抽象数据类型(ADT)的其他实现完全相同。我很惊讶在线找到套装和包包是多么困难,因为名字对于其他东西有多么常见,所以我在这里列出了一些链接和描述。

有关更多详细信息,请查看以下内容: ListsSetsBags

一般规则是:

默认情况下,

列表是有序的,如果您希望能够通过其索引提取对象,或者您对for循环foreach有一种奇怪的喜好,请使用这些}循环。您无需像Linked List中那样按顺序访问它们。此ADT允许重复。

请注意!尽管列表是按照BryanD的回答中提到的那样排序的,但绝对没有任何说明它必须按照您在执行时期望从数据库中获得的顺序HQL查询,除非您通过命令指定订单。正因为如此,有些人喜欢使用Set或Bags,因此它不会产生被命令的错觉。虽然我这么说,但大部分时间它们看起来都是可见的顺序,因为它们按照NHibernate运行的查询中的顺序添加到列表中。

默认情况下,

,您无法通过索引直接访问任何变量。默认情况下,集合中的仅限于上述三个中的ADT,以保持其对象的唯一性。如果你有一个集合,如果你不需要包含重复项,这些都很棒。

从上面的链接可以看出,

行包(或 Multisets )是一种类型的Set,它允许其中的对象与其他对象重复。通常不使用这些,因为列表排序可以忽略,因此被视为Bag。

关于如何在NHibernate中使用它们,根据您在此处选择的ADT,从数据库中提取的内容不同,这是您要使用它的原因,应该让您选择不同的ADT。

就个人而言,我使用Sets来处理大多数事情,因为我通常要求子对象是唯一的,并且排序不是问题。虽然我将使用列表,其中我有一组对象,我想按一些东西排序,例如时间,为了实现这个顺序,我需要在HQL查询中手动设置“order by”。

答案 2 :(得分:1)

主要区别在于列表对元素有一个隐式排序,由它们在列表中的位置索引。套件和行李也可以通过比较器或者当这些物品从DB出来时应用的order by子句“排序”。就个人而言,我从来没有使用过包...如果我知道我想要的数据按顺序排序我使用List,否则我使用Set。

答案 3 :(得分:0)

Set不允许您在其中包含重复元素。如果您尝试添加一些新元素,它将比较(使用等于方法)已经在集合中的每个元素与您添加的元素,如果一个返回true,则不会添加元素