我有以下问题.
我有一个带有子对象集合的父类.
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会这样做?
有人解释并可以帮我解决这个问题吗?
最佳答案 NHibernate中SQL语句的顺序是
predefined:
The SQL statements are issued in the following order
all entity insertions, in the same order the corresponding objects
were saved using ISession.Save()all entity updates
all collection deletions
all collection element deletions, updates and insertions
all collection insertions
all entity deletions, in the same order the corresponding objects
were deleted using ISession.Delete()
NHibernate认为新的子实例实际上是一个新实体.所以它首先插入它,违反了数据库约束.这意味着您有两种选择:
1)取出后和加入儿童前立即冲洗.
2)稍微改变你的设计,而不是删除/添加你只需编辑孩子.这似乎更合乎逻辑,因为看起来Child是一个由Name标识的实体.目前尚不清楚为什么你实际添加和删除相同的孩子:
Child child = parent.GetChildByName("Child1");
child.DoSomething();
或者像这样:
parent.DoSomethingWithChild("Child1");
附:我假设您的Child.Equals实现使用名称,并且在您的映射中,您有< one-to-many class =“Child”/> ;,而不是< one-to-many class =“Parent”/>.这可能只是一个错字.