2011-08-30 64 views
4

我有以下问题。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为什么这样做? 有人解释,可以帮助我解决这个问题?

回答

2

SQL语句的顺序是predefined NHibernate的:

的SQL语句会按照下面的顺序

  • 所有实体插入发行,以相同的顺序相应的对象 使用ISession.Save()保存()

  • 所有实体更新

  • 所有收集缺失

  • 所有集合元素进行删除,更新和插入

  • 所有集合插入

  • 所有实体删除,以相同的顺序相应的对象 被删除使用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" />。这可能只是一个错字。