4

次の問題があります。

子オブジェクトのコレクションを持つ親クラスがあります。

 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;
      }
 }

クラスは、列tblChild.colNameが一意のインデックスを持つデータベースのnhibernateでマップされます。

 // 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はそうするのですか?誰かが説明し、私がこの問題を解決するのを手伝ってくれる?

4

1 に答える 1

2

SQLステートメントの順序はNHibernateで事前定義されています。

SQLステートメントは次の順序で発行されます

  • すべてのエンティティの挿入、同じ順序で、対応するオブジェクトがISession.Save()を使用して保存されました

  • すべてのエンティティの更新

  • すべてのコレクションの削除

  • すべてのコレクション要素の削除、更新、および挿入

  • すべてのコレクションの挿入

  • すべてのエンティティの削除、同じ順序で、対応するオブジェクトがISession.Delete()を使用して削除されました

NHibernateは、子の新しいインスタンスは実際には新しいエンティティであると考えています。したがって、最初に挿入し、データベースの制約に違反します。これは、2つのオプションがあることを意味します。

1)子を削除した直後、および子を追加する前にフラッシュします。

2)デザインを少し変更して、削除/追加の代わりに子を編集するだけにします。子は名前で識別されるエンティティであるように見えるため、これはより論理的に見えます。同じ子を実際に追加および削除する理由は明確ではありません。

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

またはこのように:

parent.DoSomethingWithChild("Child1");

PS私はあなたのChild.Equals実装が名前を使用し、マッピングであなたが持っていると仮定し<one-to-many class="Child" />ます<one-to-many class="Parent" />。これはおそらくタイプミスです。

于 2011-08-30T23:00:02.520 に答える