一般来说多对多映射,映射表不需要设置为实体类,但如果特殊需求,如需要添加字段isActived等,这个时候就需要将映射表设置为实体,同时该实体需要针对两边的类做many-to-one映射,而两边的类需要做<bag><one-to-many>来实现双向关联,如下例:
需求:系统需要对私人(AccountInfo)发送短消息(Message),同时要统计短消息阅读状态(IsReaded),这时数据表设计如下:
首先是实体类的设计:
a.Message类
1
///
<summary>
2 /// 消息持久类
3 /// </summary>
4 [Serializable]
5 public class Message : MessageBase
6 {
7 /// <summary>
8 /// 该消息的帐户阅读状态
9 /// </summary>
10 public virtual IList < AccountMessage > Accounts{ get ; set ; }
11 }
2 /// 消息持久类
3 /// </summary>
4 [Serializable]
5 public class Message : MessageBase
6 {
7 /// <summary>
8 /// 该消息的帐户阅读状态
9 /// </summary>
10 public virtual IList < AccountMessage > Accounts{ get ; set ; }
11 }
Message映射文件
1
<?
xml version="1.0" encoding="utf-8"
?>
2 < hibernate-mapping xmlns ="urn:nhibernate-mapping-2.2" assembly ="YBValidator.Infrastructure.Core" namespace ="YBValidator.Infrastructure.Core" >
3 < class name ="YBValidator.Infrastructure.Core.Message" table ="Message" >
4 < id name ="ID" column ="MsgID" type ="int" >
5 < generator class ="native" ></ generator >
6 </ id >
7
8 < property name ="Title" column ="Title" type ="string" />
9 < property name ="InputDate" column ="InputDate" type ="DateTime" />
10 < property name ="Content" column ="MsgContent" type ="string" />
11
12 <!-- 多对一关系:一个UserInfo对应多个Message -->
13 < many-to-one name ="User" column ="UserName" not-null ="true"
14 foreign-key ="FK_Message_UserInfo"
15 ></ many-to-one >
16
17 <!-- 一对多关系 -->
18 < bag name ="Accounts" cascade ="all" inverse ="true" >
19 < key column ="MsgID" ></ key >
20 < one-to-many class ="AccountMessage" />
21 </ bag >
22 </ class >
23 </ hibernate-mapping >
2 < hibernate-mapping xmlns ="urn:nhibernate-mapping-2.2" assembly ="YBValidator.Infrastructure.Core" namespace ="YBValidator.Infrastructure.Core" >
3 < class name ="YBValidator.Infrastructure.Core.Message" table ="Message" >
4 < id name ="ID" column ="MsgID" type ="int" >
5 < generator class ="native" ></ generator >
6 </ id >
7
8 < property name ="Title" column ="Title" type ="string" />
9 < property name ="InputDate" column ="InputDate" type ="DateTime" />
10 < property name ="Content" column ="MsgContent" type ="string" />
11
12 <!-- 多对一关系:一个UserInfo对应多个Message -->
13 < many-to-one name ="User" column ="UserName" not-null ="true"
14 foreign-key ="FK_Message_UserInfo"
15 ></ many-to-one >
16
17 <!-- 一对多关系 -->
18 < bag name ="Accounts" cascade ="all" inverse ="true" >
19 < key column ="MsgID" ></ key >
20 < one-to-many class ="AccountMessage" />
21 </ bag >
22 </ class >
23 </ hibernate-mapping >
b.AccountMessage类
1
[Serializable]
2 public class AccountMessage : Entity
3 {
4 public virtual int ID { get ; set ; }
5
6 public virtual bool IsReaded { get ; set ; }
7
8 public virtual Message Message { get ; set ; }
9
10 public virtual AccountInfo Account { get ; set ; }
11 }
2 public class AccountMessage : Entity
3 {
4 public virtual int ID { get ; set ; }
5
6 public virtual bool IsReaded { get ; set ; }
7
8 public virtual Message Message { get ; set ; }
9
10 public virtual AccountInfo Account { get ; set ; }
11 }
AccountMessage映射文件
1
<?
xml version="1.0" encoding="utf-8"
?>
2 < hibernate-mapping xmlns ="urn:nhibernate-mapping-2.2" assembly ="YBValidator.Infrastructure.Core" namespace ="YBValidator.Infrastructure.Core" >
3 < class name ="YBValidator.Infrastructure.Core.AccountMessage" table ="AccountMessage" dynamic-insert ="true" dynamic-update ="true" >
4 < id name ="ID" column ="ID" type ="int" >
5 < generator class ="native" ></ generator >
6 </ id >
7 < property name ="IsReaded" column ="IsReaded" ></ property >
8
9 <!-- 一对多关系 -->
10
11 < many-to-one class ="Message" name ="Message" foreign-key ="FK_AccountMessage_Message" column ="MsgID" ></ many-to-one >
12
13 < many-to-one class ="AccountInfo" name ="Account" foreign-key ="FK_AccountMessage_AccountInfo" column ="AccName" ></ many-to-one >
14 </ class >
15 </ hibernate-mapping >
2 < hibernate-mapping xmlns ="urn:nhibernate-mapping-2.2" assembly ="YBValidator.Infrastructure.Core" namespace ="YBValidator.Infrastructure.Core" >
3 < class name ="YBValidator.Infrastructure.Core.AccountMessage" table ="AccountMessage" dynamic-insert ="true" dynamic-update ="true" >
4 < id name ="ID" column ="ID" type ="int" >
5 < generator class ="native" ></ generator >
6 </ id >
7 < property name ="IsReaded" column ="IsReaded" ></ property >
8
9 <!-- 一对多关系 -->
10
11 < many-to-one class ="Message" name ="Message" foreign-key ="FK_AccountMessage_Message" column ="MsgID" ></ many-to-one >
12
13 < many-to-one class ="AccountInfo" name ="Account" foreign-key ="FK_AccountMessage_AccountInfo" column ="AccName" ></ many-to-one >
14 </ class >
15 </ hibernate-mapping >
如上所示,在映射类(AccountMessage)中对两边的类(Message、AccountInfo)做两个many-to-one映射,而在两边的类(以Message为例),需要做一个one-to-many的映射来实现双相关联
使用的时候就有点麻烦:
使用的时候就有点麻烦:
1
IList
<
AccountMessage
>
accountMessages
=
new
List
<
AccountMessage
>
();
2 // 获取type相同的所有帐户
3 var accountInfos = accountInfoFacade.GetAccountListByShopType(type);
4 // 遍历帐户设置设置AccountMessage
5 foreach (var accountInfo in accountInfos)
6 {
7 accountMessages.Add( new AccountMessage
8 {
9 Account = accountInfo,
10 Message = message
11 });
12 }
13
14
15 message.Accounts = accountMessages;
2 // 获取type相同的所有帐户
3 var accountInfos = accountInfoFacade.GetAccountListByShopType(type);
4 // 遍历帐户设置设置AccountMessage
5 foreach (var accountInfo in accountInfos)
6 {
7 accountMessages.Add( new AccountMessage
8 {
9 Account = accountInfo,
10 Message = message
11 });
12 }
13
14
15 message.Accounts = accountMessages;