这部分不包含大量的.NET代码例子。我们假定你已经了解如何使用.NET自身的集合类框架(.NET's collections framework)和Set集合的概念。 其实如果是这样, 这里就真的没有什么东西需要学习了... 用一句话来做个总结,你就用你已经掌握的知识来使用它们吧。
NHibernate可以持久化以下集合的实例, 包括System.Collections.IDictionary
, System.Collections.IList
, Iesi.Collections.ISet
和任何持久实体或值的数组。类型为System.Collections.ILst
的属性还可以使用"bag"语义来持久。
警告:用于持久化的集合,除了集合接口外,不能保留任何实现这些接口的类所附加的语义(例如:Iesi.Collections.ListSet
带来的迭代顺序iteration order)。所有的持久化集合,实际上都各自按照System.Collections.Hashtable
, System.Collections.ArrayList
, Iesi.Collections.HashedSet
的语义直接工作。更深入地说,对于一个包含集合的属性来说,必须把.NET类型定义为接口(也就是IDictionary
, IList
或者ISet
)。存在这个限制的原因是,在你不知道的时候,NHibernate暗中把你的IDictionary
, IList
和 ISet
的实例替换成了它自己的关于这些集合的实现。(所以在你的程序中,谨慎使用==操作符。)
Cat cat = new DomesticCat(); Cat kitten = new DomesticCat(); ... Iesi.Collections.ISet kittens = new Iesi.Collections.HashedSet(); kittens.Add( kitten ); cat.Kittens = kittens; session.Save( cat ); kittens = cat.Kittens; // Okay, kittens collection is an ISet (Iesi.Collections.HashedSet)cat.Kittens; //Error! - a NHibernate.Collections.Set not Iesi.Collections.HashedSet
集合遵从对值类型的通常规则:不能共享引用, 与其包含的实体共存亡。由于存在底层的关联模型,集合不支持空值语义;并且NHibernate不会区分一个null的集合引用和一个不存在元素的空集合。
集合类在被一个持久化对象引用的时候,会自动持久化,当不再被引用时将会自动删除。如果一个集合被从一个持久化对象传递到另一个,它的元素可能会从一个表转移到另一个表。你应该不需要对此特别关心。就如同你使用普通的 .NET集合类一样使用NHibernate的集合类,但是你需要确信使用前你理解了双向关联的语义(后面会讨论)。
集合实例在数据库中根据指向对应实体的外键而得到区别。这个外键被称为集合的关键字。在NHibernate配置文件中使用 <key>
元素来映射这个集合的关键字。
集合可以包含几乎所有的其他NHibernate类型, 包括所有的基本类型, 自定义类型,实体类型和组件。有一条重要的定义:在集合中的对象可以通过“传值”语义(完全依赖于集合自身)操作,也可以是一个指向其他实体的引用,拥有自己的生命周期。集合不能包含其他集合。这些被包含的元素的类型被称为集合元素类型。集合的元素在Hibernate中被映射为<element>
,<composite-element>
,<one-to-many>
,<many-to-many>
或者<many-to-any>
。前两种用传值语义操作元素,另外三种则映射实体关联。
除了ISet
和Bag之外的所有集合类型都有一个索引(index)字段,这个字段映射到一个数组或者IList
的索引或者IDictionary
的key。IDictionary
的索引的类型可以是任何基本类型, 实体类型或者甚至是一个组合类型(但不能是一个集合类型)。数组和IList
的索引肯定是整型(Int32
)。在NHibernate配置文件中使用 <index>
,<index-many-to-many>
,<composite-index>
或者<index-many-to-any>
等元素来映射索引。
集合类可以产生相当多种类的映射,涵盖了很多通常的关系模型。我们建议你练习使用schema生成工具, 以便对如何把不同的映射定义转换为数据库表有一个感性认识。