NHibernate删除并添加ParentClass的ChildCollection
我有以下问题。
我有一个包含子对象集合的父类。
public class Parent{
int _id;
IList<Child> _childs = new List<Child>();
public IList<Child> Childs {get;}
}
public class Child{
int _id;
string _name;
Parent _parent;
protected Child(){}
public Child(Parent parent, string name){
_parent = parent;
_name = name;
}
}
这些类使用 nhibernate 映射到数据库,其中 tblChild.colName 列具有唯一索引。
// Parent
<bag name="_childs" access="field" cascade="all-delete-orphan" inverse="true">
<key column="ParentId" />
<one-to-many class="Parent" />
</bag>
// Child
<many-to-one name="_parent" column="ParentId" cascade="none" access="field">
我的问题: 下面的代码由于唯一索引而抛出异常:
Parent parent = new Parent();
Child child1 = new Child(parent, "Child1");
Child child2 = new Child(parent, "Child2");
Child child3 = new Child(parent, "Child3");
parent.Childs.Add(child1);
parent.Childs.Add(child2);
parent.Childs.Add(child3);
parentDao.Save(parent);
parentDao.FlushAndClear();
Child child4 = new Child(parent, "Child1"); // Duplicate Name
parent.Childs.Remove(child1);
parent.Childs.Add(child4);
parentDao.Save(parent);
parentDao.FlushAndClear();
异常的原因是NHibernate先插入child4,然后删除child1。 NHibernate 为什么要这样做? 有人解释并可以帮助我解决这个问题吗?
I have the following problem.
I have a parent class with a collection of child objects.
public class Parent{
int _id;
IList<Child> _childs = new List<Child>();
public IList<Child> Childs {get;}
}
public class Child{
int _id;
string _name;
Parent _parent;
protected Child(){}
public Child(Parent parent, string name){
_parent = parent;
_name = name;
}
}
The classes are mapped with nhibernate for database where the column tblChild.colName has a unique index.
// Parent
<bag name="_childs" access="field" cascade="all-delete-orphan" inverse="true">
<key column="ParentId" />
<one-to-many class="Parent" />
</bag>
// Child
<many-to-one name="_parent" column="ParentId" cascade="none" access="field">
My problem:
The following code throw exception because of unique index:
Parent parent = new Parent();
Child child1 = new Child(parent, "Child1");
Child child2 = new Child(parent, "Child2");
Child child3 = new Child(parent, "Child3");
parent.Childs.Add(child1);
parent.Childs.Add(child2);
parent.Childs.Add(child3);
parentDao.Save(parent);
parentDao.FlushAndClear();
Child child4 = new Child(parent, "Child1"); // Duplicate Name
parent.Childs.Remove(child1);
parent.Childs.Add(child4);
parentDao.Save(parent);
parentDao.FlushAndClear();
The reason for the exception is that NHibernate first inserts child4 and then removes child1. Why does NHibernate do so?
Someone an explaination and can help me resolving this problem?
SQL 语句的顺序是在 NHibernate 中预定义的:
NHibernate 认为 child 的新实例实际上是一个新实体。因此它首先插入它,这违反了您的数据库约束。这意味着您有两个选择:
1)在删除之后和添加子项之前立即刷新。
2)稍微改变一下你的设计,这样你就可以简单地编辑子项,而不是删除/添加。这看起来更合乎逻辑,因为看起来 Child 是一个由 Name 标识的实体。目前尚不清楚为什么您实际上添加和删除相同的子项:
或像这样:
PS 我假设您的 Child.Equals 实现使用名称,并且在您的映射中您有
;
,而不是
。这可能只是一个错字。The order of SQL statements is predefined in NHibernate:
NHibernate thinks that new instance of child is actually a new entity. So it inserts it first, violating your database constraint. It means that you have two options:
1) Flush immediately after removing and before adding child.
2) Change your design a bit so that instead of Remove/Add you simply edit the child. This seems more logical because it looks like Child is an entity that is identified by Name. It is not clear why you actually adding and removing same child:
or like this:
P.S. I assume your Child.Equals implementation uses name and in your mapping you have
<one-to-many class="Child" />
, not<one-to-many class="Parent" />
. This is probably just a typo.