多对多关系在数据库也是比较常见的,它通过一个中间表将两个主表关联起来。
下面来看看多对多关联在nh的实现,示例是一个User和Group之间的多对多关联。
先来看看User类的映射信息:
在多对多定义中,定义了中间表为UserGroups,此表只有两个字段:user_id和group_id;用于关联Users和Groups表。
User的定义:
public class User
{
public User() {
}
public int UserId
{
get { return userId; }
set { userId = value; }
}
public
int Name
{
get { return name; }
set { name = value;
}
}
public IDictionary Groups
{
get { return
groups; }
set { groups = value; }
}
private int
userId;
private string name;
private IDictionary groups = new
Hashtable();
} //class
User
这里用一个数据字典IDictionary对角来保存组对象。
再来看看Group类的映射信息:
这里many-to-many的定义和User类映射信息中的差不多。
组类的定义:
public class Group
{
public Group() {
}
public int GroupId
{
get { return groupId; }
set { groupId = value; }
}
public int Name
{
get { return name; }
set {
name = value; }
}
public int Description
{
get {
return description; }
set { description = value; }
}
public IDictionary Users
{
get { return users; }
set {
users = value; }
}
private int groupId;
private string
name;
private IDictionary users = new Hashtable();
} //class
Group
注意:多对多没有主次之分,保存时的两边都要save!
下面给出部分测试代码。
public TestCreate()
{
User user1 = new User();
user1.Name = "test1";
User user2 =
new User();
user2.Name = "test2";
Group group1 = new
Group();
group1.Name = "group1";
Group group2 = new Group();
group2.Name = "group2";
user1.Groups.Add( group2, group2 );
user2.Groups.Add( group1. group1 );
group1.Users.Add( user2, user2
);
group2.Users.Add( user1, user1 );
ITransactioin trans =
null;
try {
trans = session.BeginTransaction();
Session.Save( user1 );
Session.Save( user2 );
Session.Save(
group1 );
Session.Save( group2 );
trans.Commit();
}
catch ( Exception e ) {
if ( trans != null )
trans.Rollback();
throw e;
}
finally {
session.Close();
}
}
以上测试代码中session的相关操作请查看相关文档。
在实际应用中,我较少使用many-to-many映射,当然这要从性能和实际需要考虑。
我的做法是一个elements来取得所有关联的identity,
然后在需要的时候才加载对象,有点类似lazy,
但lazy有一个问题,就是session必须没有被释放,这在分层开发中较难办到。
原文:
http://www.seaskyer.net/Index/Catalog44/182.html