映射(Mapping)之多对多
“多对多”比起“一对一”来说似乎很简单。也没什么需要更多的叙述。也来举个例子,有两表分别是User、Group。很明显,每个user可以同属于多个group;而每个group也可以有多个user;这就是两表间的多对多关系。我们通常利用第三个表来保存这种关系,在这个例子中,我们将这个第三个表命名为UserGroup。
看看我们的对应两表的类CUser、CGroup的代码
public class CUser

public class CGroup

再看看映射文件
user.hbm.xml
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="EnPrint.DB.CUser,EnPrint.DB" table="[User]">
<id name="ID" column="ID" type="Int32">
<generator class="identity" />
</id>
<property name="Password" column="[Password]" type="string" length="50" />
<property name="Name" column="[Name]" type="string" length="50" />
<set name="Groups" table="UserGroup" inverse="true">
<key column="User_ID"/>
<many-to-many column="Group_ID" class="EnPrint.DB.CGroup,EnPrint.DB"/>
</set>
</class>
</hibernate-mapping>group.hbm.xml
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="EnPrint.DB.CGroup,EnPrint.DB" table="[Group]">
<id name="ID" column="ID" type="Int32">
<generator class="identity" />
</id>
<property name="Name" column="[Name]" type="string" length="50" />
<property name="Memo" column="[Memo]" type="string" length="50" />
<set name="Users" table="UserGroup">
<key column="Group_ID"/>
<many-to-many column="User_ID" class="EnPrint.DB.CUser,EnPrint.DB"/>
</set>
</class>
</hibernate-mapping>
使用nUnit的部分测试代码
看看我们的对应两表的类CUser、CGroup的代码
public class CUser

public class CGroup

再看看映射文件
user.hbm.xml
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="EnPrint.DB.CUser,EnPrint.DB" table="[User]">
<id name="ID" column="ID" type="Int32">
<generator class="identity" />
</id>
<property name="Password" column="[Password]" type="string" length="50" />
<property name="Name" column="[Name]" type="string" length="50" />
<set name="Groups" table="UserGroup" inverse="true">
<key column="User_ID"/>
<many-to-many column="Group_ID" class="EnPrint.DB.CGroup,EnPrint.DB"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="EnPrint.DB.CGroup,EnPrint.DB" table="[Group]">
<id name="ID" column="ID" type="Int32">
<generator class="identity" />
</id>
<property name="Name" column="[Name]" type="string" length="50" />
<property name="Memo" column="[Memo]" type="string" length="50" />
<set name="Users" table="UserGroup">
<key column="Group_ID"/>
<many-to-many column="User_ID" class="EnPrint.DB.CUser,EnPrint.DB"/>
</set>
</class>
</hibernate-mapping>使用nUnit的部分测试代码
CUser usr = new CUser();
usr.Name = "kevin";
usr.Password = "111111";
CGroup grp = new CGroup();
grp.Name = "Admin";
usr.Groups.Add(grp);
grp.Users.Add(usr);
session.Save(grp);
session.Save(usr);
transaction.Commit();
usr.Name = "kevin";
usr.Password = "111111";
CGroup grp = new CGroup();
grp.Name = "Admin";
usr.Groups.Add(grp);
grp.Users.Add(usr);
session.Save(grp);
session.Save(usr);
transaction.Commit();
能说的,只是在多对多时,我们一般操控的是三张表,我们的代码只需两个类。第三张表只是用来保存两者这间的多对多关系,不是一个实体。
至于效率什么的,不在这里说了,文档和网上有一些叙述。需要注意的是,我使用的是NHibernate1.0(0.99.2.0)的版本,需要使用ISet接口来保存Users。使用IList、IDictionary用会引起一个类型转换错误。网上有文章使用NHibernate 0.9.1.0的示例代码是使用IDictionary的。
注:文章所使用的C+表名来作为类名的命名规则在生成表时会有问题。
http://kevin-Y.cnblogs.com/archive/2006/01/12/315716.html



}
浙公网安备 33010602011771号