HasAndBelongsToMany

Mar 11, 2009 at 10:42 AM
首选非常感谢你提供这么优秀的框架:)

在使用过程中,我又遇到了一些问题:
在使用HasAndBelongsToMany时,
自动创建的表里,会有很多重复信息。每Save一次就多一次关系。(Oracle10g中)

难道是需要特别去设置数据库Unique?
这样代码又会违反规定而报错。(是还需要TryCatch……?)

还有一个问题,如果在多对多的关系建立时,不只是关系本身,还有很多和个关系相关的附加内容。
例如。。
例如一个读者读了一本书,读书后的读后感,评价等等信息要怎么建立模型来存呢?。。
Coordinator
Mar 11, 2009 at 12:23 PM
第一个问题,我基本上没看懂。你可以给出例子代码么?

第二个问题,参见 这个帖子 9楼、10楼。
Mar 11, 2009 at 4:33 PM
Edited Mar 12, 2009 at 2:04 AM
(非常抱歉,描述的不清楚,我修改了一下……)

1.我是使用Oracle10g作为数据库的,
在模型中使用多对多的[HasAndBelongsToMany]标记时,
DBEntry会自动创建一个中间表例如:User_Role

User user=User.New().Init("MyUser");
Role role=Role.New().Init("MyRole");
user.Roles.Add(role);
user.Save();//保存一次。
……
role.Name = "ReName";
user.Role.Add(role);//因为某些原因,又添加了一次。
user.Save();//再次保存。

那么在中间表里就会出现,重复的表关系
每执行一次user.Role.Add(role),就多一条没有检查是不是已经存在。……:
userId roleId
1 1
1 1
Add方法是不是应该判断一下,是否有重复的?
(是不是本来就允许重复?)
如果要限制其重复,而又不去手动修改Oracle表的情况下要怎么做呢?


2.第二个问题,看到了您说的提示,其实就是等于不要使用[HasAndBelongsToMany],而是自己建立关系表。
public abstract class Xref_User_Room
{
    public abstract string Note { get; set; }
    [BelongsTo] public User User { get; set; }
    [BelongsTo] public Room Room { get; set; }
}

但是这样用起来似乎有缺少了 例如:User.Rooms 这种直接的关系的便利调用。
变成:User.Xref_User_Room  得到HasMany<Xref_User_Room>,然后再循环 取:Xref_User_Room.Room。
不知道是不是有其他的方法,可以改进这样的使用方式……

Coordinator
Mar 12, 2009 at 11:53 AM
第一个问题,保存多次是没有问题的,不过,你确实不能添加两次。这个问题我想我大概不会试图解决。在DbEntry的关系设计中,对于添加项,不会读取所有关系项后再进行,既然有可能没有读取所有项,也就不能完全判断是否有重复。如果你已经读出了所有子项,可能你还是用user.Roles.Contains(role)之类的函数判断一下更好。

第二个问题,我不知道有另外的方法,我也觉得应该不会有其他的方法。这个方法也是hibernate文档中推荐的方法——hibernate并不推荐使用ManyToMany。(不知道NHibernate的文档中有没有写入这一段)