NHibernate删除并添加ParentClass的ParentCollection

时间:2011-08-30 14:35:44

标签: nhibernate parent-child unique-index

我有以下问题。

我有一个包含子对象集合的父类。

 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会这样做? 有人解释并可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

NHibernate中SQL语句的顺序为predefined

  

SQL语句按以下顺序发布

     
      
  • 所有实体插入,按相同顺序对应的对象   使用ISession.Save()

  • 保存   
  • 所有实体更新

  •   
  • 所有收集删除

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

  •   
  • 所有收集插入

  •   
  • 所有实体删除,按相同顺序对应的对象   使用ISession.Delete()

  • 删除   

NHibernate认为新的child实例实际上是一个新实体。所以它首先插入它,违反了数据库约束。这意味着您有两个选择:

1)在移除后和添加孩子之前立即冲洗。

2)稍微改变你的设计,这样你就可以编辑孩子而不是删除/添加。这似乎更合乎逻辑,因为看起来Child是一个由Name标识的实体。目前尚不清楚为什么要实际添加和删除相同的孩子:

Child child = parent.GetChildByName("Child1");
child.DoSomething();

或者像这样:

parent.DoSomethingWithChild("Child1");

P.S。我假设您的Child.Equals实现使用了名称,在您的映射中,您有<one-to-many class="Child" />,而不是<one-to-many class="Parent" />。这可能只是一个错字。