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,实现方法差不说,就不多说了。
源码下载:点我。