首页 新闻 会员 周边 捐助

Nhibernate Many to Many 之 Update

0
悬赏园豆:5 [已关闭问题]

刚学习Nhibernate遇到了这个问题

用常用的用户和角色来描述many to many的问题:

下面是映射文件(使用FluentNHibernate生成后去掉了省略掉部分):

 

代码
<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="User">
.......
<bag cascade="all" lazy="true" name="Roles" table="S_UserInRole" mutable="true">
<key>
<column name="UID" />
</key>
<many-to-many class="Role">
<column name="RID" />
</many-to-many>
</bag>
</class>

<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="Role">
.......
<bag cascade="all" lazy="true" name="Users" table="S_UserInRole" mutable="true" inverse="true">
<key>
<column name="RID" />
</key>
<many-to-many class="User">
<column name="UID" />
</many-to-many>
</bag>
</class>

 

 

代码
public void AddUserToRole(string userID, string roleID)
{
using (ISession _session = SessionFactory.Get().OpenSession())
{
using (ITransaction tran = _session.BeginTransaction())
{
try
{
MSRole role
= _session.Get<MSRole>(roleID);
MSUser u
= role.Users.FirstOrDefault(o => o.ID == userID);
if (null == u)
{
MSUser entity
= _session.Load<MSUser>(userID);
//entity.ID = userID;
//entity.Roles = new List<MSRole>();

role.Users.Add(entity);
entity.Roles.Add(role);
_session.Update(entity); //_session.Update(role);
_session.Flush();
}
tran.Commit();
}
catch (HibernateException)
{
tran.Rollback();
throw;
}
}
}
}
AddUserToRole("35a74933-e881-4f85-bf95-24592d7e6796","1128");
用Nunit测试 得到Nhibernate产生的sql语句:
NHibernate: INSERT INTO S_UserInRole (UID, RID) VALUES (@p0, @p1);@p0 = '35a74933-e881-4f85-bf95-24592d7e6796', @p1 = '1128'
NHibernate: DELETE FROM S_UserInRole WHERE UID = @p0;@p0 = '35a74933-e881-4f85-bf95-24592d7e6796'
NHibernate: INSERT INTO S_UserInRole (UID, RID) VALUES (@p0, @p1);@p0 = '35a74933-e881-4f85-bf95-24592d7e6796', @p1 = 'f089cee5-9cac-4301-b988-d224619ca263'
(上面Insert为S_UserInRole表原有的一条记录)
NHibernate: INSERT INTO S_UserInRole (UID, RID) VALUES (@p0, @p1);@p0 = '35a74933-e881-4f85-bf95-24592d7e6796', @p1 = '1128'

//预想的是只需要最后一条SQL语句,而Nhibernate却是先删除所有再insert

 

 

代码
public void RemoveUserFromRole(string userID, string roleID)
{
using (ISession _session = SessionFactory.Get().OpenSession())
{
using (ITransaction tran = _session.BeginTransaction())
{
try
{
MSRole entity
= _session.Get<MSRole>(roleID);
if (null != entity)
{
MSUser user
= entity.Users.FirstOrDefault(o => o.ID == userID);
if (user != null)
{
entity.Users.Remove(user);
user.Roles.Remove(entity);

_session.Update(user);//_session.Update(entity);
_session.Flush();
tran.Commit();
}
}
}
catch (HibernateException)
{
tran.Rollback();
throw;
}
}
}
}

RemoveUserFromRole("35a74933-e881-4f85-bf95-24592d7e6796","1128");
测试 Nhibernate生成的sql语句为:
NHibernate: DELETE FROM S_UserInRole WHERE UID = @p0;@p0 = '35a74933-e881-4f85-bf95-24592d7e6796' NHibernate: INSERT INTO S_UserInRole (UID, RID) VALUES (@p0, @p1);@p0 = '35a74933-e881-4f85-bf95-24592d7e6796', @p1 = 'f089cee5-9cac-4301-b988-d224619ca263'

// 预想 SQL:DELETE FROM S_UserInRole WHERE UID = @p0 and RID=@p1;@p0 = '35a74933-e881-4f85-bf95-24592d7e6796',@p1='1128'
//

 

按上面我的写法,Nhibernate会先把中间表中所有关联记录删除掉再重新insert,每添加一次对应关系,都会先删除所有对应关系再重新insert就太不合理了。

上面的映射文件和代码该如何修改

readonly的主页 readonly | 菜鸟二级 | 园豆:406
提问于:2010-06-17 11:34
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册