【发布时间】:2021-06-02 03:19:54
【问题描述】:
NHibernate 映射文件中的 list、set 和 bag 有什么区别?每个与 .NET 集合有什么关系?
【问题讨论】:
标签: nhibernate
NHibernate 映射文件中的 list、set 和 bag 有什么区别?每个与 .NET 集合有什么关系?
【问题讨论】:
标签: nhibernate
NHibernate 语义:
列表:实体的有序集合,允许重复。在代码中使用 .NET IList。索引列需要在 NHibernate 中映射。
Set:唯一实体的无序集合,不允许重复。在代码中使用Iesi.Collection.ISet(NH v4 之前)或System.Collections.Generic.ISet(NH v4+)。覆盖GetHashCode 和Equals 以指示重复的业务定义很重要。可以通过定义 orderby 或通过定义导致 SortedSet 结果的比较器进行排序。
Bag:实体的无序列表,允许重复。在代码中使用 .NET ICollection<T>。列表的索引列未映射且不受 NHibernate 支持。
【讨论】:
ISet 而不是Iesi吗?
NHibernate 中的所有这些对象都与这些抽象数据类型 (ADT) 的其他实现完全相同。我很惊讶在网上找到 Sets 和 Bags 有多么困难,因为这些名称对于其他东西来说是多么常见,所以我在这里列出了一些链接和描述。
有关更多详细信息,请查看以下内容: Lists, Sets 和 Bags
一般规则是:
列表 默认情况下是有序的,如果您希望能够通过索引提取对象或者您对for 循环超过foreach 循环有一种奇怪的喜爱,请使用这些。您不需要像在Linked List 中那样按顺序访问它们。此 ADT 允许重复。
请注意!虽然列表按照 BryanD 在他的回答中提到的顺序排列,绝对没有说它必须按照您在执行时从数据库中获得的顺序HQL 查询,除非您通过命令指定顺序。 正是因为如此,有些人喜欢使用 Set 或 Bags 来代替,这样它就不会产生被排序的错觉。虽然我这么说,但大多数情况下,它们会以可见的顺序出现,因为它们是按照在 NHibernate 运行的查询中找到的顺序添加到列表中的。
集合默认是非有序的,你不能通过索引直接访问任何变量。默认情况下,集合是上述三个中唯一保持其对象唯一性的 ADT。如果您需要不包含重复项,则如果您有一个集合,这些非常好。
Bags(或 Multisets)是,正如您从上面的链接中看到的那样,是一种允许其中的对象与其他对象重复的 Set .这些通常不使用,因为可以忽略列表排序,因此将其视为 Bag。
关于这些在 NHibernate 中的使用方式,根据您在此处选择的 ADT,从数据库中提取的内容不会有所不同,这就是您想要使用它的目的,这应该使您选择不同的 ADT。
就我个人而言,我在大多数事情上都使用 Set,因为我通常要求子对象是唯一的,并且排序不是问题。虽然我将使用列表,其中我有一组对象,我希望按某些东西(例如时间)排序,以实现此顺序,但我需要在 HQL 查询中手动设置“排序依据”。
【讨论】:
主要区别在于列表对元素有隐式排序,由它们在列表中的位置索引。套装和袋子通常也可以通过 Comparator 或 order by 子句“排序”,当这些项目从 DB 中出来时应用。就个人而言,我从未使用过 Bags ...如果我知道我想要的数据是按顺序排序的,我会使用 List,否则我会使用 Set。
【讨论】:
Set 不允许您在其中包含重复的元素。如果您尝试添加一些新元素,它将比较(使用 Equals 方法)已经在集合中的每个元素与您添加的元素,如果返回 true,则不会添加元素
【讨论】: