引用:http://blog.csdn.net/liangxunjian/archive/2006/08/11/1048625.aspx
主要是关于:<composite-id>元素接受<key-property>
将在使用复合主键(2)中讲到<key-many-to-one>
属性映射我目前在实施一个.net项目中,使用了ORM工具,参考了java的hibernate,选用了.NET的NHibernate,在开发过程中出现数据库中表的复合主键的情况,其实它跟hibernate中使用的复合主键的情况雷同,但参照了相关的帮助文档,还是要费了一些小的工夫,才能解决了问题.为了避免以后再出现重复问题而浪费时间,现在将在NHibernate中复合主键使用做了以下详细的说明.
本人在测试过程中,建立了一个简单的图书馆管理系统应用工程,数据库中主要的表简要设计如下:
Users表(用户信息表):
UserID char(10) not null primary key,
UserName varchar(50)
Books表(图书信息表):
BSN char(10) not null primary key,
BookName varchar(50)
BorrowRecord表(图书借还登记表):
UserID char(10) not null,
BSN char(10) not null,
BorrowDate DateTime not null,
ReturnDate DateTime,
constraint PK_Library primary key (UserID,BSN,BorrowDate)
手工书写的ORM映射文件如下:
======================================================================
User类:
using System;
using System.Collections.Generic;
using System.Text;
namespace NHDataLayer.NHibernate.Entities
{
[Serializable]
public class User
{
public User()
{
}
private string userID;
public virtual string UserID
{
set
{
userID = value;
}
get
{
return userID;
}
}
private string userName;
public virtual string UserName
{
set
{
userName = value;
}
get
{
return userName;
}
}
}
}
User的xml映射文件(User.hbm.xml):
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="NHDataLayer.NHibernate.Entities.User,NHDataLayer" table="Users">
<id name="UserID" type="String" length="10">
<generator class="assigned" />
</id>
<property name="UserName" type="String" length="50"/>
</class>
</hibernate-mapping>
=====================================================================
======================================================================
Books类:
using System;
using System.Collections.Generic;
using System.Text;
namespace NHDataLayer.NHibernate.Entities
{
[Serializable]
public class Books
{
public Books()
{
}
private string bSN;
public virtual string BSN
{
set
{
bSN = value;
}
get
{
return bSN;
}
}
private string bookName;
public virtual string BookName
{
set
{
bookName = value;
}
get
{
return bookName;
}
}
private DateTime publishDate;
public virtual DateTime PublishDate
{
set
{
publishDate = value;
}
get
{
return publishDate;
}
}
private string publisher;
public virtual string Publisher
{
set
{
publisher = value;
}
get
{
return publisher;
}
}
private string authors;
public virtual string Authors
{
set
{
authors = value;
}
get
{
return authors;
}
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}
Books的xml映射文件(Book.hbm.xml):
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="NHDataLayer.NHibernate.Entities.Books,NHDataLayer" table="Books">
<id name="BSN" type="String" length="20">
<generator class="assigned" />
</id>
<property name="BookName" type="String" length="50"/>
<property name="PublishDate" type="DateTime"/>
<property name="Publisher" type="String" length="100"/>
<property name="Authors" type="String" length="50"/>
</class>
</hibernate-mapping>
==================================================================
===================================================================
BorrowRecord类:
using System;
using System.Collections.Generic;
using System.Text;
namespace NHDataLayer.NHibernate.Entities
{
[Serializable]
public class BorrowRecord
{
public BorrowRecord()
{
}
private BorrowRecordPK borrowPK;
public virtual BorrowRecordPK BorrowPK
{
set
{
borrowPK = value;
}
get
{
return borrowPK;
}
}
private int total;
public virtual int Total
{
set
{
total = value;
}
get
{
return total;
}
}
private DateTime returnDate;
public virtual DateTime ReturnDate
{
set
{
returnDate = value;
}
get
{
return returnDate;
}
}
/// <summary>
/// 判断两个对象是否相同,这个方法需要重写
/// </summary>
/// <param name="obj">进行比较的对象</param>
/// <returns>真true或假false</returns>
public override bool Equals(object obj)
{
if (obj is BorrowRecord)
{
BorrowRecord second = obj as BorrowRecord;
if (this.BorrowPK.UserID == second.BorrowPK.UserID
&& this.BorrowPK.BSN == second.BorrowPK.BSN
&& this.BorrowPK.BorrowDate == second.BorrowPK.BorrowDate)
{
return true;
}
else return false;
}
return false;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}
BorrowRecord复合主键类:
using System;
using System.Collections.Generic;
using System.Text;
namespace NHDataLayer.NHibernate.Entities
{
[Serializable]
public class BorrowRecordPK
{
public BorrowRecordPK()
{
}
private string userID;
public virtual string UserID
{
set
{
userID = value;
}
get
{
return userID;
}
}
private string bSN;
public virtual string BSN
{
set
{
bSN = value;
}
get
{
return bSN;
}
}
private DateTime borrowDate;
public virtual DateTime BorrowDate
{
set
{
borrowDate = value;
}
get
{
return borrowDate;
}
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}
BorrowRecord的xml映射文件(BorrowRecord.hbm.xml):
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="NHDataLayer.NHibernate.Entities.BorrowRecord,NHDataLayer" table="BorrowRecord">
<composite-id name="BorrowPK" class="NHDataLayer.NHibernate.Entities.BorrowRecordPK,NHDataLayer">
<key-property name="UserID"/>
<key-property name="BSN"/>
<key-property name="BorrowDate"/>
</composite-id>
<property name="ReturnDate" type="DateTime"/>
<property name="Total" type="Int16"/>
</class>
</hibernate-mapping>
==============================================================================
主要要注意的是:
1、使用了复合主键类要重写Equals()和GetHashCode()方法。
2、要将该复合类Serializable.
3、xml映射文件要设置为嵌入的资源。
这样,我们就可以使用ISession的Get()或Load()方法,通过键获取实体了。
关于更详细的信息,请参考NHibernate的相关文档。