p到对象c的连接(外键parent_id)没有被当作是Child对象状态的一部分,也没有在INSERT的时候被创建。解决的办法是,在Child一端设置映射。
<many-to-one name="Parent" column="parent_id" not-null="true"
(我们还需要为类Child添加Parent属性)
现在实体Child在管理连接的状态,为了使collection不更新连接,我们使用inverse属性。
<set name="Children" inverse="true">
<key column="parent_id" />
<one-to-many class="Child" />
</set>
下面的代码是用来添加一个新的Child
Parent p = session.Load( typeof( Parent ), pid ) as Parent;
Child c = new Child();
c.Parent = p;
p.Children.Add( c );
session.Save( c );
session.Flush();
![]()
现在,只会有一条INSERT语句被执行!
为了让事情变得井井有条,可以为Parent加一个AddChild()方法
public void AddChild( Child c )
...{
this.Children.Add( c );
c.Parent = this;
}
![]()
AddChild把代码简化了
Parent p = session.Load( typeof( Parent ), pid ) as Parent;
Child c = new Child();
p.AddChild( c ); //
session.Save( c );
session.Flush();
![]()
对每个对象调用Save() ()方法很麻烦,我们可以用级联来解决这个问题。
<set name="Children" inverse="true" cascade="all">
<key column="parent_id" />
<one-to-many class="Child" />
</set>
配置级联以后,代码就简化了:
Parent p = session.Load( typeof( Parent ), pid ) as Parent;
Child c = new Child();
p.AddChild( c );
session.Flush();
![]()
注意
级联十分依赖unsaved-value属性(attribute)。请确保<id>属性(property)的默认值和unsaved-value一样。
类似的,当保存或删除Parent时我们不需要遍历children。下面的代码从数据库中删除了p和它所有的children。