代码改变世界

NHibernate3剖析:Mapping篇之集合映射基础(2):Bag映射

2010-05-10 21:33 by 李永京, ... 阅读, ... 评论, 收藏, 编辑

本节内容

系列引入

NHibernate3.0剖析系列分别从Configuration篇、Mapping篇、Query篇、Session策略篇、应用篇等方面全面揭示NHibernate3.0新特性和应用及其各种应用程序的集成,基于NHibernte3.0版本。如果你还不熟悉NHibernate,可以快速阅读NHibernate之旅系列文章导航系列入门,如果你已经在用NHibernate了,那么请跟上NHibernate3.0剖析系列吧。

Bag映射

这节我们介绍Bag映射,一般而言,Domain中的System.Collections.Generic.ICollection<T>集合类型使用Bag来映射。

映射纲要

Bag映射与Set映射一样,有两个部分:集合外键(Collection foreign keys)和集合元素(Collection element)。

集合外键(Collection foreign keys),通过<key>映射,其column属性命名方式一般采用"集合持有者类名+Id"命名方式。

集合元素(Collection element),即集合中的对象:

  • 值类型,其声明周期完全依赖于集合持有者,通过<element>或<composite-element>映射。
  • 引用类型,被作为集合持有的状态考虑的,只有两个对象之间的“连接”,具有其自己的生命周期,通过<one-to-many>或<many-to-many>映射。

案例分析

案例一:BagOfElements

Domain定义中,集合元素一般是单一元素(Elements)类型,即.Net基本类型(string、int、double等等)。

//Code Snippets Copyright http://lyj.cnblogs.com/
public class BagOfElements
{
    public int Id { get; set; }
    public ICollection<string> Elements { get; set; }
}

映射简单写法:

//Code Snippets Copyright http://lyj.cnblogs.com/
<class name="BagOfElements">
  <id name="Id" type="Int32">
    <generator class="hilo" />
  </id>
  <bag name="Elements" table="BagOfElementsElements">
    <key column="BagOfElementsId" />
    <element type="String" />
  </bag>
</class>

单一元素类型在NHibernate中使用<element>映射的,我们应该至少指定column和type类型,如果column没指定,NHibernate提供默认列名id。

数据库架构:

BagOfElements

案例二:BagOfComponents

Domain定义中,集合元素一般是组件(Component)类型,也就是值类型。

//Code Snippets Copyright http://lyj.cnblogs.com/
public class BagOfComponents
{
    public int Id { get; set; }
    public ICollection<ComponentBag> Components { get; set; }
}

public class ComponentBag
{
    public string StringProperty { get; set; }
    public int IntProperty { get; set; }
}

映射简单写法:

//Code Snippets Copyright http://lyj.cnblogs.com/
<class name="BagOfComponents">
  <id name="Id" type="Int32">
    <generator class="hilo" />
  </id>
  <bag name="Components">
    <key column="BagOfComponentsId" />
    <composite-element class="ComponentBag">
      <property name="StringProperty" />
      <property name="IntProperty" />
    </composite-element>
  </bag>
</class>

组件(Component)类型使用composite-element映射,需要指明组件类名,然后映射其组件属性。

数据库架构:

BagOfComponents

案例三:BagOfComponentsWithParent

Domain定义中,集合元素一般是组件(Component)类型,这个组件关联了其持有者。

//Code Snippets Copyright http://lyj.cnblogs.com/
public class BagOfComponentsWithParent
{
    public int Id { get; set; }
    public ICollection<ComponentsWithParent> ComponentsWithParents { get; set; }
}

public class ComponentsWithParent
{
    public BagOfComponentsWithParent Owner { get; set; }
    public string StringProperty { get; set; }
    public int IntProperty { get; set; }
}

映射简单写法:

//Code Snippets Copyright http://lyj.cnblogs.com/
<class name="BagOfComponentsWithParent">
  <id name="Id" type="Int32">
    <generator class="hilo" />
  </id>
  <bag name="ComponentsWithParents">
    <key column="BagOfComponentsWithParentId" />
    <composite-element class="ComponentsWithParent">
      <parent name="Owner" />
      <property name="StringProperty" />
      <property name="IntProperty" />
    </composite-element>
  </bag>
</class>

数据库架构:

BagOfComponentsWithParent

案例四:BagOfNestedComponentsWithParent

Domain定义中,集合元素一般是组件(Component)类型,这个组件关联了其持有者并且嵌套了一个组件类型。

//Code Snippets Copyright http://lyj.cnblogs.com/
public class BagOfNestedComponentsWithParent
{
    public int Id { get; set; }
    public ICollection<NestedComponents> NestedComponents { get; set; }
}

public class NestedComponents
{
    public BagOfNestedComponentsWithParent Owner { get; set; }
    public string StringProperty { get; set; }
    public NestedComponentsWithParent NestedComponentsWithParent { get; set; }
}

public class NestedComponentsWithParent
{
    public NestedComponents OwnerNestedComponent { get; set; }
    public int IntProperty { get; set; }
}

映射简单写法:

//Code Snippets Copyright http://lyj.cnblogs.com/
<class name="BagOfNestedComponentsWithParent">
  <id name="Id" type="Int32">
    <generator class="hilo" />
  </id>
  <bag name="NestedComponents">
    <key column="BagOfNestedComponentsWithParentId" />
    <composite-element class="NestedComponents">
      <parent name="Owner" />
      <property name="StringProperty" />
      <nested-composite-element class="NestedComponentsWithParent">
        <parent name="OwnerNestedComponent" />
        <property name="IntProperty" />
      </nested-composite-element>
    </composite-element>
  </bag>
</class>

数据库架构:

BagOfNestedComponentsWithParent

案例五:BagOfOneToMany

Domain定义中,集合元素是指向另一个实体OneToManyBag的引用。这里设置为一对多关系。

//Code Snippets Copyright http://lyj.cnblogs.com/
public class BagOfOneToMany
{
    public int Id { get; set; }
    public ICollection<OneToManyBag> OneToMany { get; set; }
}

public class OneToManyBag
{
    public int Id { get; set; }
}

映射简单写法:

//Code Snippets Copyright http://lyj.cnblogs.com/
<class name="BagOfOneToMany">
  <id name="Id" type="Int32">
    <generator class="hilo" />
  </id>
  <bag name="OneToMany">
    <key column="BagOfOneToManyId" />
    <one-to-many class="OneToManyBag" />
  </bag>
</class>
<class name="OneToManyBag">
  <id name="Id" type="Int32">
    <generator class="hilo" />
  </id>
</class>

我们为BagOfOneToMany和OneToManyBag定义一对多关系,使用<one-to-many>映射,指明关联的对象。

数据库架构:

BagOfOneToMany

案例六:BagOfManyToMany

Domain定义中,集合元素是指向另一个实体ManyToManyBag的引用。这里设置为多对多关系。

//Code Snippets Copyright http://lyj.cnblogs.com/
public class BagOfManyToMany
{
    public int Id { get; set; }
    public ICollection<ManyToManyBag> ManyToMany { get; set; }
}

public class ManyToManyBag
{
    public int Id { get; set; }
}

映射简单写法:

//Code Snippets Copyright http://lyj.cnblogs.com/
<class name="BagOfManyToMany">
  <id name="Id" type="Int32">
    <generator class="hilo" />
  </id>
  <bag name="ManyToMany" table="BagOfManyToManyToManyToManyBag">
    <key column="BagOfManyToManyId" />
    <many-to-many class="ManyToManyBag" column="ManyToManyBagId" />
  </bag>
</class>
<class name="ManyToManyBag">
  <id name="Id" type="Int32">
    <generator class="hilo" />
  </id>
</class>

两个对象的多对多关系,需要一个“中间表”来存储这两个对象的关系。

数据库架构:

BagOfManyToMany

结语

开始NH剖析的Mapping篇,这篇文章介绍NHibernate中的集合映射之Bag映射。

希望本文对你有所帮助。