天天看点

[NHibernate]集合类(Collections)映射

<a href="http://www.cnblogs.com/wolf-sun/p/3694592.html">[nhibernate]体系结构</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3694901.html">[nhibernate]isessionfactory配置</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3704012.html">[nhibernate]持久化类(persistent classes)</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3705229.html">[nhibernate]o/r mapping基础</a>

这部分不包括大量的.net代码例子。我们假定你已经了解如何使用.net自身的集合类框架(.net's collections framework)和set集合的概念。其实如果是这样,这里就真的没有什么东西需要学习了....用一句话来做个总结,你就用你已经掌握的知识来使用他们吧。

nhibernate可以持久化以下集合的实例,包括system.collections.idictionary,system.collections.ilist,lesi.collectons.iset和任何持久实体或值的数组。类型为system.collections.ilist的属性还可以使用“bag”语义来持久。

警告:用于持久化的集合,除了集合接口外,不能保留任何实现这些接口的类所附加的语义(例如:lesi.collectons.listset带来的迭代顺序iteration order)。所有的持久化集合,实际上都各自按照system.collections.hashtable,system.collections.arraylist,lesi.collections.hashset的语义直接工作。更深入地说,对于一个包含集合的属性来说,必须把.net类型定义为接口(也就是idictionary,ilist或者iset)。存在这个限制的原因是,在你不知道的时候,nhibernate暗中把你的idictionary,ilist和iset的实例替换成了它自己的关于这些集合的实现。(所以在你的程序中,谨慎使用==操作符)

[NHibernate]集合类(Collections)映射
[NHibernate]集合类(Collections)映射

集合遵从对值类型的通常规则:不能共享引用,与其包含的实体共存亡。由于存在底层的关联模型,集合不支持空值语义;

并且nhibernate不会区分一个null的集合引用和一个不存在元素的空集合。

集合类在被一个持久化对象引用的时候,会自动持久化,当不再被引用时将会自动删除。如果一个集合被从一个持久化对象传递到另一个,它的元素可能会从一个表转移到另一个表。你应该不需要对此特别关心。就如同你使用普通的 .net集合类一样使用nhibernate的集合类,但是你需要确信使用前你理解了双向关联的语义(后面会讨论)。

集合实例在数据库中根据指向对应实体的外键而得到区别。这个外键被称为集合的关键字。在nhibernate配置文件中使用 &lt;key&gt; 元素来映射这个集合的关键字。

集合可以包含几乎所有的其他nhibernate类型, 包括所有的基本类型, 自定义类型,实体类型和组件。有一条重要的定义:在集合中的对象可以通过“传值”语义(完全依赖于集合自身)操作,也可以是一个指向其他实体的引用,拥有自己的生命周期。集合不能包含其他集合。这些被包含的元素的类型被称为集合元素类型。集合的元素在hibernate中被映射为&lt;element&gt;, &lt;composite-element&gt;, &lt;one-to-many&gt;, &lt;many-to-many&gt; 或者&lt;many-to-any&gt;。前两种用传值语义操作元素,另外三种则映射实体关联。

除了iset和bag之外的所有集合类型都有一个索引(index)字段,这个字段映射到一个数组或者ilist的索引或者idictionary的key。idictionary的索引的类型可以是任何基本类型, 实体类型或者甚至是一个组合类型(但不能是一个集合类型)。数组和ilist的索引肯定是整型(int32)。在nhibernate配置文件中使用 &lt;index&gt;,&lt;index-many-to-many&gt; ,&lt;composite-index&gt; 或者&lt;index-many-to-any&gt;等元素来映射索引。

集合类可以产生相当多种类的映射,涵盖了很多通常的关系模型。我们建议你练习使用schema生成工具, 以便对如何把不同的映射定义转换为数据库表有一个感性认识。

值集合和多对多关联(collections of values and many-to-many associations)

 一对多关联(one-to-many associations)

&lt;延迟初始化(延迟加载)(lazy initialization)

集合排序(sorted collections)

使用 &lt;idbag&gt;

双向关联(bidirectional associations)

双向关联允许通过关联的任一端访问另外一端。在nhibernate中,支持两种类型的双向关联:

一对多(one-to-many):

&lt;set&gt;或者&lt;bag&gt;值在一端, 单独值(非集合)在另外一端。

多对多(many-to-many)

两端都是&lt;set&gt;或&lt;bag&gt;值

请注意nhibernate不支持带有索引的集合(ilist,idictionary或者数组)作为“多”的那一端的双向one-to-many关联,你必须使用集合或者bag映射。

要建立一个双向的多对多关联,只需要映射两个many-to-many关联到同一个数据库表中,并再定义其中的一端为inverse(使用哪一端要根据你的选择)。这里有一个从一个类关联到他自身的many-to-many的双向关联的例子(每一个category都可以有很多items,每一个items可以属于很多categories):

[NHibernate]集合类(Collections)映射
[NHibernate]集合类(Collections)映射

如果只对关联的反向端进行了改变,这个改变不会被持久化。这表示nhibernate为每个双向关联在内存中存在两次表现,一个从a连接到b,另一个从b连接到a。如果你回想一下.net对象模型,我们是如何在.net中创建多对多关系的,这可以让你更容易理解:

非反向端用于把内存中的表示保存到数据库中,如果两端都进行了改变,我们会进行多余的insert/update,甚至可能得到外键冲突!这一点对双向的一对多关联也是一样的。

要建立一个一对多的双向关联,你可以通过把一个一对多关联,作为一个多对一关联映射到同一张表的字段上,并且在“多”的那一端定义inverse=“true”,

[NHibernate]集合类(Collections)映射
[NHibernate]集合类(Collections)映射

在“一”这一端定义inverse=“true”不会影响级联操作,二者是不同的概念。

三重关联(ternary associations)

异类关联(heterogeneous associations)

介绍对集合持久化,如何映射集合的方法。

本文来自《nhibernate 中文文档》

博客地址:

<a href="http://www.cnblogs.com/wolf-sun">http://www.cnblogs.com/wolf-sun/</a>

博客版权:

本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。

如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!

再次感谢您耐心的读完本篇文章。

转载:http://www.cnblogs.com/wolf-sun/p/3714577.html