商讯信箱
用户名: @
密  码:   注册|忘记密码
登录
个人用户经销商
信箱 E杂志
您的位置:首页 > 技术频道 > 正文

NHibernate文档-示例: Parent/Child

作者:DDLLY命名空间  2007-04-26
级联更新(Using cascading update()

假设我们从ISession中装入了一个Parent对象,用户界面对其进行了修改,然后我们希望在一个新的ISession里面调用 Update()来更新它。对象Parent包含了子对象的集合,由于打开了级联更新,NHibernate需要知道哪些子对象是新的,哪些是数据库中已经存在的。我们假设ParentChild对象的标识属性的类型为System.Int32。NHibernate会使用标识属性的值来判断哪些子对象是新的。(你也可以使用version 或 timestamp 属性)

unsaved-value属性是用来表示新实例的标识属性值的,缺省为"null",对于.net的值类型(ValueTypes)这不是一个好的默认值,所以你需要提供unsaved-value

如果我们使用原始类型作为标识类型的话,我们在配置Child类映射的时候就必须写:

<id name="Id" type="Int64" unsaved-value="0">

对于Child 映射. (也有unsaved-value属性(attribute)提供给版本(version)和时间戳(timestamp)属性(property)映射)

下面的代码会更新parentchild对象,并且插入newChild对象。

//parent and child were both loaded in a 上一页ious session parent.AddChild( child ); Child newChild = new Child(); parent.AddChild( newChild ); session.Update( parent ); session.Flush();
好的,对于自动生成标识的情况这样做很方便,但是自分配的标识和复合标识怎么办呢?这是有点麻烦,因为unsaved-values无法区分新对象(标识是用户指定的)和前一个ISession装入的对象。在这种情况下,你可能需要给NHibernate一些提示,在调用update(parent)之前:
  • 在这个类的 <version> or <timestamp>属性映射上定义unsaved-value="null"或者unsaved-value="negative"

  • 在对父对象执行Update( parent )之前,设定unsaved-value="none" 并且显式的调用Save()在数据库创建新子对象

  • 在对父对象执行Update( parent )之前,设定unsaved-value="any"并且显式的调用 Update()更新已经装入的子对象

none是自分配标识和复合标识的unsaved-value的缺省值。

结论

这个问题往往让新手感到迷惑,它确实不太容易消化。不过,经过一些实践以后,你会感觉越来越顺手。父子对象模式已经被广泛的应用在NHibernate应用程序中。

在第一段中我们曾经提到另一个方案。复合元素的语义与父子关系是等同的,但是我们并没有详细讨论。很不幸复合元素还有两个重大限制:复合元素不能拥有collections,并且,除了用于惟一的父对象外,它们不能再作为其它任何实体的子对象。(但是,通过使用 <idbag>映射,它们可能拥有代理主键。)

1 2 3 4
【内容导航】
第1页: 第1页 第2页: 第2页
第3页: 第3页 第4页: 第4页
©版权所有。未经许可,不得转载。
[责任编辑:孙蓬阳]