nhibernate入门系列: many-to-many映射
多对多关系在数据库也是比较常见的,它通过一个中间表将两个主表关联起来。
下面来看看多对多关联在nh的实现,示例是一个User和Group之间的多对多关联。
先来看看User类的映射信息:
在多对多定义中,定义了中间表为UserGroups,此表只有两个字段:user_id和group_id;用于关联Users和Groups表。
User的定义:
这里用一个数据字典IDictionary对角来保存组对象。
再来看看Group类的映射信息:
这里many-to-many的定义和User类映射信息中的差不多。
组类的定义:
注意:多对多没有主次之分,保存时的两边都要save!
下面给出部分测试代码。
以上测试代码中session的相关操作请查看相关文档。
在实际应用中,我较少使用many-to-many映射,当然这要从性能和实际需要考虑。
我的做法是一个elements来取得所有关联的identity, 然后在需要的时候才加载对象,有点类似lazy, 但lazy有一个问题,就是session必须没有被释放,这在分层开发中较难办到。
下面来看看多对多关联在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
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
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();
}
}
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必须没有被释放,这在分层开发中较难办到。