我在数据库中的两个表之间有一个识别关系。
父表具有通过Identity生成的主键。子表有一个主键,它是父表中标识生成的主键。这是真正的一对一。
我尝试了几种映射策略,各种结果,都不是完美的。
父映射文件具有此功能(注意Cascade.All() - 我希望父级管理关系):
HasOne(x => x.ChildObject).Cascade.All();
子映射具有:
Id(Reveal.Member<ChildObject>("ID"))
.GeneratedBy.Foreign("ParentObject");
HasOne(Reveal.Member<ChildObject, ParentObject>("ParentObject"))
.Constrained()
.ForeignKey();
我更改了对象名称以保护无辜者。
所以这就是发生的事情。我创建了一个父实例,我创建了一个子实例并设置了关系(将Child添加到Parent,将Parent添加到Child)。
我运行此代码:
session.SaveOrUpdate(_Parent);
session.Clear();
transaction.Commit();
我期望发生的是父保存,其中ID在数据库的父级中更新。然后应在Child中设置ID,并保存Child。
相反,Parent被保存,但不是Child(我可以看到nHibernate正在执行的insert语句,并且Child对象永远不会出现在数据库中)。
Child拥有来自父级的ID(它正在从Parent传播到Child),但是nHibernate不会将Child识别为脏(我的猜测)。即使我在Child对象上显式尝试SaveOrUpdate,它也不会被保存。
但它有点怪异。如果我将一组脏对象附加到Child,并且我在Child上调用SaveOrUpdate ,则nHhiberante将持久保存Child和集合 - 预期的行为。但我仍然必须明确地称之为。
我在绘制亲子关系时犯了什么错误?
答案 0 :(得分:1)
我的猜测是parent.Id是由身份生成的。
行session.SaveOrUpdate(_Parent);
将保存父级以获取其ID并缓存子级的插入以在提交时刷新。然后,session.Clear();
将删除缓存的插入内容,transaction.Commit();
将无法找到任何操作。