我有两个表,tableA和tableB。
tableA具有列:tabAId,col2,col3 (tabAId primaryKey和Identity列。)
tableB具有列:tabAId,名称 (tabAId不为空)
我在tableA的hbm文件中创建了Bag,以维护关系。
<bag name="tableB" lazy="true" inverse="false" batch-size="25" cascade="all-delete-orphan"> <key column="tabAId" /> <one-to-many class="tableB" /> </bag>
当我尝试更新 tableA中的 记录时,它将引发异常,因为我在tableA实例中有子项列表。
[NHibernate.Exceptions.GenericADOException] = {“无法删除集合:[MIHR.Entities.tableA.tableB#21] [SQL:UPDATE dbo.tableB SET tabAId = null WHERE tabAId = @ p0]”} InnerException = {“无法将值NULL插入表’SA_MIHR_DEV.dbo.tableB’的列’tabAId’中;该列不允许为空。UPDATE失败。\ r \ n该语句已终止。”}
[NHibernate.Exceptions.GenericADOException] = {“无法删除集合:[MIHR.Entities.tableA.tableB#21] [SQL:UPDATE dbo.tableB SET tabAId = null WHERE tabAId = @ p0]”}
InnerException = {“无法将值NULL插入表’SA_MIHR_DEV.dbo.tableB’的列’tabAId’中;该列不允许为空。UPDATE失败。\ r \ n该语句已终止。”}
只有两种方法可以解决此问题。
1)不要使用 inverse="false"
inverse="false"
<bag name="tableB" lazy="true" inverse="true" // instead of false batch-size="25" cascade="all-delete-orphan"> <key column="tabAId" /> <one-to-many class="tableB" /> </bag>
此设置 (inverse =“ true”) 将指示NHibernate直接从数据库中删除 项目 。
虽然使用inverse="false"will通常会导致:
2)使引用列可为空
这意味着,我们可以让NHibernate进行UPDATE和DELETE。因为column现在可以为空。
这些只是这里解决问题的两种方法。
我的偏好是: inverse =“ true”
为了正常工作, inverse="true" 我们总是必须在C#中分配关系的两端。这对于Add(),INSERT操作是必须的:
inverse="true"
Parent parent = new Parent(); Child child = new Child { ... Parent = parent, }; // unless initialized in the Parent type, we can do it here parent.Children = parent.Children ?? new List<Child>(); parent.Children.Add(child); // now just parent could be saved // and NHibernate will do all the cascade as expected // and because of inverse mapping - the most effective way session.Save(parent);
如我们所见,我们 已经 明确 指定 了关系的双方。必须从NHibernate逆映射中获利。这也是一个好习惯,因为稍后,当我们期望从数据库加载数据时,NHibernate将为我们设置该设置