Nhibernate 3.0 cookbook学习笔记 一对多与多对多映射

1 一对多映射

还是用Movie与ActorRole来说明。我们假设一个Movie可以有多个ActorRole,而一个ActorRole只能对应一个Movie。

设置一对多映射主要是父类(Movie)要做相应的更改。我们在Movie类中要增加一个集合,用来表示该Movie下的所有ActorRole。

 public class Movie : Product 
    {
        public virtual string Director { get; set; }
        //ActorRole集合,用于列举该Movie下的所有ActorRole
        public virtual IList<ActorRole> Actors { get; set; }
    }

相应的我们的Movie.hbm.xml也要做相应的更改,增加一个list节点

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NhibernageMap.Entity"
namespace="NhibernageMap.Entity">
  <subclass name="Movie" extends="Product">
    <property name="Director" />
      <list name="Actors" cascade="all-delete-orphan">
        <!--对应父类的主键,子类中的外键-->
          <key column="MovieId" />
        <!--list中index值-->
          <index column="ActorIndex" />
        <!--对应的子类-->
          <one-to-many class="ActorRole"/>
      </list>
  </subclass>
</hibernate-mapping>

ActorRole很简单,只有两个字段:

 public class ActorRole : Entity 
    {
        public virtual string Actor { get; set; }
        public virtual string Role { get; set; }
    }

对应的ActorRole.hbm.xml:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="NhibernageMap.Entity"
    namespace="NhibernageMap.Entity">
  <class name="ActorRole">
    <id name="Id">
      <generator class="guid.comb" />
    </id>
    <version name="Version" />
    <property name="Actor" not-null="true" />
    <property name="Role" not-null="true" />
  </class>
</hibernate-mapping>

我们用一个方法向数据库中插入两条数据:

View Code
 private void CreateMovies(ISession session)
        {
            session.Save(
                new Movie()
                {
                    Name = "Raiders of the Lost Ark",
                    Description = "Awesome",
                    UnitPrice = 9.59M,
                    Director = "Steven Spielberg",
                    Actors = new List<ActorRole>()
                    {
                    new ActorRole()
                        {
                            Actor = "Harrison Ford",
                            Role = "Indiana Jones"
                        }
                    }
                }
        );
            session.Save(
                    new Movie()
                    {
                        Name = "The Bucket List",
                        Description = "Good",
                        UnitPrice = 15M,
                        Director = "Rob Reiner",
                        Actors = new List<ActorRole>()
                        {
                            new ActorRole()
                            {
                                Actor = "Jack Nicholson",
                                Role = "Edward Cole"
                            },
                            new ActorRole()
                            {
                                Actor = "Morgan Freeman",
                                Role = "Carter Chambers"
                            }
                        }
                    }
                );
        }

 

看下数据库中两张表的存储状况

在Product表中我们新增了两个Movie:

 

再看看ActorRole表:

可以看到ActorRole表中有三条记录,而后面两要是对应同个MoiveId的。

 

2 多对多映射

 多对多其实就是两个一对多,中间要生成第三张表来转换。我们用Movie与Actor来说明 。

 我们新增一个Actor类:

  public class Actor : Entity
    {
        //姓名
        public virtual string ActorName { get; set; }
        //性别
        public virtual bool ActorSex { get; set; }
        //对应的Movie集合
        public virtual IList<Movie> Movies { get; set; }
    }

设置对应的Actor.hbm.xml:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="NhibernageMap.Entity"
    namespace="NhibernageMap.Entity">
  <class name="Actor">
    <id name="Id">
      <generator class="guid.comb" />
    </id>
    <version name="Version" />
    <property name="ActorName" not-null="true" />
    <property name="ActorSex" not-null="true" />
    <!--bag集合设置多对多的关联-->
    <!--name:Actor.cs中对应的集合类名-->
    <!--table:要生成的第三张表的名称-->
    <bag name="Movies" table="MovieActor">
      <!--column:表的主键-->
      <key column="ActorId"/>
      <!--class:多对多映射的类名 column:对应的外键-->
      <many-to-many class="Movie" column="MovieId"/>
    </bag>
  </class>
</hibernate-mapping>

相应的修改Movie.cs,增加一个Actor集合:

  public class Movie : Product 
    {
        public virtual string Director { get; set; }
        //ActorRole集合,用于列举该Movie下的所有ActorRole
        public virtual IList<ActorRole> ActorRoles { get; set; }
        //Actor集合
        public virtual IList<Actor> Actors { get; set; }
    }

修改Movie.hbm.xml,增加以下内容:

 <bag name="Actors" table="MovieActor">
      <key column="MovieId"/>
      <many-to-many class="Actor" column="ActorId"/>
    </bag>

我们新增一个测试数据,通过新增Actor来新增Movie:

View Code
private void CreateActor(ISession session)
        {
            var movie1 = new Movie()
            {
                Name = "黄金大劫案",
                Description = "喜剧",
                UnitPrice = 10.59M,
                Director = "宁浩",
                ActorRoles = new List<ActorRole>()
                    {
                    new ActorRole()
                        {
                            Actor = "陶虹",
                            Role = "芳蝶"
                        },
                         new ActorRole()
                        {
                            Actor = "雷佳音",
                            Role = "小东北"
                        }
                    },
                
            };
        
            var actor1 = new Actor()
            {
                ActorName = "陶虹",
                ActorSex = false,
                Movies = new List<Movie>() { movie1
                }
            };
            var actor2 = new Actor()
            {
                ActorName = "雷佳音",
                ActorSex = true,
                Movies = new List<Movie>() { movie1
                }
            };
            session.Save(movie1);
            session.Save(actor1);
            session.Save(actor2);
        }

 

执行后查看数据库
Actor表中数据,新增了两个记录:

 

再看看Product中的Movie记录,新增了一条:

 

最后是中间表MovieActor:

 

我们看到有两个ActorId对应同一个MoiveId.

当然我们也可以通过新增Movie来新增Actor,实现方法差不说,就不多说了。

源码下载:点我

posted @ 2012-05-20 14:55  Gyoung  阅读(1376)  评论(3编辑  收藏  举报