NHibernate一对多 - 为什么用null外键更新子进程?

时间:2011-08-10 14:38:30

标签: nhibernate fluent-nhibernate

我正在对正在尝试更新已断开连接的实体的代码进行故障排除,该实体具有对子实体的未初始化引用。目的是仅更新Parent上的属性而不加载子项。

HasMany(x => x.ChildEntities)
  .KeyColumn("ChildEntityId")
  .Table("ChildEntity")
  .Not.LazyLoad()
  .Inverse()
  .Cascade.All().AsBag();

调用Session.Update(父级)时,将执行两个更新语句。第一个按预期更新父对象。

update Parent set ... where ParentId = 12345

第二次更新让我感到困惑......

update ChildEntity set ParentId = null where ParentId = 12345

为什么NHibernate会发出第二个SQL语句?我意识到ChildEntities是未初始化的,并且NHibernate可能正在尝试强制执行Parent的状态,但我似乎无法调整映射以不进行第二次更新。我已经尝试过Merge,延迟加载,各种级联选项等,但没有成功。在尝试提交时,会话中唯一连接的实体是Parent。

请注意,我通常通过检索启用了延迟加载的实体,然后在将NHibernate持久保存到数据库之前从断开连接的对象(DTO或实体)映射到连接的实体来实现此目的。在我提出另一种方法之前,我想了解上述原因无法解决的原因。

1 个答案:

答案 0 :(得分:4)

这很烦人。

快速搜索NHibernate源代码中的“无法删除集合”显示在一个块中,该块只能在!isInverse(AbstractCollectionPersister.cs)中执行。这引起了我的注意,因为映射代码在该集合上明确设置了Inverse。

如果Inverse为false且集合为空,则NH对子表执行更新,将外键设置为null,其中外键等于父ID。

Fluent配置为自动映射给定命名空间中的所有实体。假设自动映射会忽略任何带有手动映射的内容。快速检查Fluent生成的hbm.xml文件,确认没有设置Inverse。我将Parent添加到明确从Auto Mapping中排除的实体列表中,一切都开始工作。

.IgnoreBase<Parent>()
相关问题