NHibernate删除并添加ParentClass的ParentCollection

我有以下问题.

我有一个带有子对象集合的父类.

 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”/&gt ;,而不是< one-to-many class =“Parent”/>.这可能只是一个错字.

点赞