我刚学习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>
答案 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
。这也更快。