Nhibernate多对多映射

    一般来说多对多映射,映射表不需要设置为实体类,但如果特殊需求,如需要添加字段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{ getset; }
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>
 
 
 
    b.AccountMessage类
 1     [Serializable]
 2     public class AccountMessage : Entity
 3     {
 4         public virtual int ID { getset; }
 5 
 6         public virtual bool IsReaded { getset; }
 7 
 8         public virtual Message Message { getset; }
 9 
10         public virtual AccountInfo Account { getset; }
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>
 
 
如上所示,在映射类(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;
 
posted @ 2011-03-11 14:14  str.chan  阅读(499)  评论(1编辑  收藏  举报