【问题标题】:NHibernate parent mapping does not create child foreign-keyNHibernate 父映射不创建子外键
【发布时间】:2009-12-17 05:45:28
【问题描述】:

我只是在学习 NHibernate。我一直在使用文档中的示例以及在 stackoverflow 中的示例,但我一定遗漏了一些东西。

我有一个包含 CHILD 集合的 PARENT 对象。没有 PARENT 的 CHILD 毫无意义,因此数据库将 FK 设置为 NOT NULL。实现从 CHILD 到 PARENT 的 NHibernate 效果很好,尽管我不需要这种关系方向。

相反,我尝试实现拥有该关系的 PARENT,但我始终收到一个数据库错误冒泡“无法将值 NULL 插入 PARENT_ID”。保存时,ID 和 PARENT 的实体都没有存储在 CHILD 中。

请参阅下面的代码示例。请指教。

类文件

public class PARENT {
   private readonly IList<CHILD> _children = new List<CHILD>();
   public virtual Id { get; set; }
   public virtual void AddChild(CHILD child) {
      _children.add(child);
   }
}
public class CHILD {
   public virtual Id { get; set; }
}

映射

<class name="PARENT" table="Parent">
  <cache usage="read-write"/>

  <id name="Id" column="Id" unsaved-value="0" >
    <generator class="identity" />
  </id>

  <bag name="Children" access="field.camelcase-underscore" cascade="all-delete-orphan">
    <key column="ParentId"/>
    <one-to-many class="CHILD"/>
  </bag>

</class>
<class name="CHILD" table="Child">
  <cache usage="read-write"/>

  <id name="Id" column="Id" unsaved-value="0" >
    <generator class="identity"/>
  </id>

</class>

【问题讨论】:

  • 不确定你是否知道,但是,请到这里 -> summerofnhibernate.com 了解 NHibernate 上的一些非常好的截屏视频!

标签: c# .net nhibernate


【解决方案1】:

您必须在映射和对象模型中定义关系的双方。然后,您在映射中将其声明为inverse="true"。所以这样的事情应该可以工作:

类文件

public class PARENT {
   private readonly IList<CHILD> _children = new List<CHILD>();
   public virtual Id { get; set; }
   public virtual void AddChild(CHILD child) {
      _children.add(child);
   }
}
public class CHILD {
   public virtual PARENT Parent { get; set; }
   public virtual Id { get; set; }
}

映射

<class name="PARENT" table="Parent">
  <cache usage="read-write"/>

  <id name="Id" column="Id" unsaved-value="0" >
    <generator class="identity" />
  </id>

  <bag name="Children" access="field.camelcase-underscore"
     cascade="all-delete-orphan" inverse="true">
    <key column="ParentId"/>
    <one-to-many class="CHILD"/>
  </bag>

</class>
<class name="CHILD" table="Child">
  <cache usage="read-write"/>

  <id name="Id" column="Id" unsaved-value="0" >
    <generator class="identity"/>
  </id>
  <many-to-one name="Parent" class="PARENT" column="ParentId" />

</class>

您可能希望将您的 AddChild 方法更改为:

public virtual void AddChild(CHILD child) {
   _children.add(child);
   child.Parent = this;
}

【讨论】:

  • 感谢您的回复!对于 CHILD 映射,“类”不是“属性”的有效属性。我尝试删除它,但它无法确定 PARENT 的类型。我还尝试将“属性”更改为“多对一”,但这导致了我之前尝试插入空外键的错误。
  • 那行得通,但我仍然有“无法将值 NULL 插入 PARENT_ID”。我的步骤是,创建 PARENT,持久化 PARENT,刷新,将子添加到 PARENT,持久化 PARENT,错误,Cry,尝试 Stackoverflow。
  • 您是否按照我在编辑中的替换 AddChild 方法中所建议的那样在 Child 上设置 Parent 属性?
  • 您已更改 AddChild 方法以设置对父级的引用?
  • 优秀,添加“child.Parent = this;”工作..这是预期的行为吗?我原以为 NHibernate 会为我处理这个问题。
【解决方案2】:

我遇到了同样的问题,现在我只是删除了这种外键的非空约束。由于该数据库仅与 NH 一起使用,因此无法在此处获取任何空值。

我认为 NHibernate 首先存储孩子。然后它存储父级。因为您需要身份 ID,所以在将其插入数据库之前,它没有父级的主键。然后它需要在之后更新孩子。

尝试另一个 id 生成器。推荐hilo。这也更快。

【讨论】:

  • 不幸的是,数据库是从几个不同的客户端使用的,所以我更喜欢直接在数据库中维护这种完整性。
猜你喜欢
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多