NHibernate Удалить и добавить в ChildCollection Of ParentClass - PullRequest
4 голосов
/ 30 августа 2011

У меня следующая проблема.

У меня есть родительский класс с коллекцией дочерних объектов.

 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 Ответ

2 голосов
/ 31 августа 2011

Порядок операторов SQL: предопределенный в NHibernate:

Операторы SQL выдаются в следующем порядке

  • всесущность вставки , в том же порядке соответствующие объекты были сохранены с использованием ISession.Save ()

  • все обновления сущностей

  • вся коллекция удаления

  • все удаления, обновления и вставки всех элементов коллекции

  • все вставки коллекции

  • все удаления сущностей, в том же порядке соответствующие объекты были удалены с помощью ISession.Delete ()

NHibernate считает, что новый экземпляр child на самом деленовая сущность.Поэтому он вставляет его первым, нарушая ограничения вашей базы данных.Это означает, что у вас есть два варианта:

1) Очистить сразу после удаления и перед добавлением дочернего элемента.

2) Немного изменить свой дизайн, чтобы вместо Remove / Add вы просто редактировали дочерний элемент,Это кажется более логичным, потому что похоже, что Child - это объект, который идентифицируется по Name.Непонятно, почему вы на самом деле добавляете и удаляете одного и того же потомка:

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

или как это:

parent.DoSomethingWithChild("Child1");

PS Я предполагаю, что ваша реализация Child.Equals использует имя и в вашем отображенииесть <one-to-many class="Child" />, а не <one-to-many class="Parent" />.Вероятно, это просто опечатка.

...