涤生之Enjoy code

General principles of programmer

导航

many2many的写法与注意点

所谓many2many就是多对多关系,如人员与权限;人员与部门等。

多对多可以将关联表作为一个实体,相关系的表均采用One2Many方法引用这个关联实体。另外一种就是采用真正的Many2Many方式,如下:

在这种情况下,多对多操纵的是三张表,但只有两个实体类。中间的关系表在Nhibernate中是不当作实体来处理的。

示例代码用的是人员与部门。两个类的写法相同,本文以User与Department为例子。

Department.Hbm.xml

<bag name="Users" table="TBL_USER_DEP" lazy="true">

      
<key column="DEPARTMENT_ID"/>

      
<many-to-many column="USER_ID" class="NHibernateStudy.Domain.User, NHibernateStudy.Domain"/>

</bag>

 

注意:name 属性为在Department类中引用的User数据的名称;

      Table属性:为关联表的名称;lazy属性为延迟加载

严重注意:此处不能加入Inverse=true,刚开始加入这个,导致关系表数据插入不进去。仔细思考一下可知,此时关联表对应的无实体类,而将inverse=true实际上是将关系交给many即关联表对应的实体类,而关联表压根没有实体类,所以也就不可能插入。

       Key column属性指定当前类在关联表中的列的名称,即关联表与该表连接的外键名称

       Many-to-many属性 column:指定,对应的那个类在关联表中的字段,对于Deparment来说就是User类对应的表在关联表中的列。即关联表与User类对应表连接的外键名称。

 

Cs

private IList<User> users = new List<User>();

public virtual IList<User> Users

        
{

            
get return users; }

            
set { users = value; }

        }


注意: 在变量声明时即生成数组实例。也可以在构造函数中完成此操作。

 

编译与调用



protected void Button4_Click(object sender, EventArgs e)

    
{

        NHibernateStudy.Domain.User newUser 
= new NHibernateStudy.Domain.User();

        

        newUser.UserName 
= "zhyuque";

        newUser.Password 
= "abc1231";

        newUser.EmailAddress 
= "zhyuque@cool.com1";

        newUser.LastLogon 
= DateTime.Now;

 

        Deparment newDep 
= new Deparment();

        newDep.Name 
= "新员工培训部";

 

       Deparment newDep1 
= new Deparment();

        newDep1.Name 
= "人事部";

 

        newUser.Deparments.Add(newDep);

        newUser.Deparments.Add(newDep1);

        
//newDep.Users.Add(newUser);  加入此句话,导致关联表主键重复

        
//newDep1.Users.Add(newUser); 加入此句话,导致关联表主键重复

 

 

        
string sTmp = "Congratulate, We are succeed!";

        ISession session 
= Sessions.GetSession();

        ITransaction trans 
= session.BeginTransaction();

 

        
try

        
{

            session.Save(newDep);

            session.Save(newDep1);

            session.Save(newUser);

           

            trans.Commit();

        }


        
catch

        
{

            trans.Rollback();

            sTmp 
= "Sorry, Please try again!";

        }


        
finally

        
{

            session.Close();

        }


 

        
this.TbxHello.Text = sTmp;

        

}


 

在调用与编译中一共出现两个问题

1) 关联表数据无法插入,问题解决见上文inverse=true;

2) 插入数据报异常。关键问题就是

        newUser.Deparments.Add(newDep);

        newUser.Deparments.Add(newDep1);

        
//newDep.Users.Add(newUser);  加入此句话,导致关联表主键重复

        
//newDep1.Users.Add(newUser); 加入此句话,导致关联表主键重复

如果互相加入,会导致主键重复,所以只需要有一方操作关联表即可

posted on 2007-07-19 16:56  涤生  阅读(668)  评论(1编辑  收藏  举报