无法删除集合:[NHibernate.Exceptions.GenericADOException]
could not delete collection : [NHibernate.Exceptions.GenericADOException]
我有两个 Table,tableA 和 tableB。
tableA 有列:tabAId、col2、col3 (tabAId 主键和标识列。)
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] = {"could not delete collection: [MIHR.Entities.tableA.tableB#21][SQL: UPDATE dbo.tableB SET tabAId = null WHERE tabAId = @p0]"}
InnerException = {"Cannot insert the value NULL into column 'tabAId', table 'SA_MIHR_DEV.dbo.tableB';
column does not allow nulls. UPDATE fails.\r\nThe statement has been terminated."}
只有两种方法可以解决这个问题。
1) 不要使用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 直接从数据库中删除一个 item。
虽然使用 inverse="false"
通常会导致:
- UPDATE(空值)== 从集合中删除的行为
- 删除项目 == 级联行为
2) 使引用列可为空
这意味着,我们可以让 NHibernate 进行更新和删除。因为列现在可以为空。
这里只有两种解决方法。
我的偏好是:inverse="true"
为了与 inverse="true"
正常工作,我们总是必须在 C# 中分配关系的两边。这是Add(), INSERT操作必须的:
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 会负责为我们设置
我有两个 Table,tableA 和 tableB。
tableA 有列:tabAId、col2、col3 (tabAId 主键和标识列。)
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] = {"could not delete collection: [MIHR.Entities.tableA.tableB#21][SQL: UPDATE dbo.tableB SET tabAId = null WHERE tabAId = @p0]"}
InnerException = {"Cannot insert the value NULL into column 'tabAId', table 'SA_MIHR_DEV.dbo.tableB'; column does not allow nulls. UPDATE fails.\r\nThe statement has been terminated."}
只有两种方法可以解决这个问题。
1) 不要使用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 直接从数据库中删除一个 item。
虽然使用 inverse="false"
通常会导致:
- UPDATE(空值)== 从集合中删除的行为
- 删除项目 == 级联行为
2) 使引用列可为空
这意味着,我们可以让 NHibernate 进行更新和删除。因为列现在可以为空。
这里只有两种解决方法。
我的偏好是:inverse="true"
为了与 inverse="true"
正常工作,我们总是必须在 C# 中分配关系的两边。这是Add(), INSERT操作必须的:
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 会负责为我们设置