NHibernate父映射不会创建子外键

时间:2009-12-16 21:23:35

标签: c# .net nhibernate

我刚学习NHibernate。我一直在使用文档中的示例和stackoverflow,但我必须遗漏一些东西。

我有一个包含CHILD集合的PARENT对象。没有PARENT,CHILD没有意义,因此数据库的FK设置为​​NOT NULL。从CHILD到PARENT实现NHibernate工作正常,但我不需要这种关系方向。

相反,我试图实现拥有该关系的PARENT,但我一直得到一个数据库错误冒泡“无法将值NULL插入PARENT_ID”。保存时,父母的ID和实体都没有存储在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>

2 个答案:

答案 0 :(得分:2)

您必须在映射和对象模型中定义关系的两侧。然后在映射中将其声明为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;
}

答案 1 :(得分:0)

我遇到了同样的问题,现在我刚刚删除了这种外键的非空约束。由于数据库仅用于NH,因此无法获得任何空值。

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

尝试另一个id生成器。建议hilo。这也更快。