0

マッピングを少し変更した後 ( 理由については、cascade-delete に関する他の質問を参照してください)、完全に新しいオブジェクトとそのすべてのサブクラスを挿入しようとしました。

この別の問題が発生した後、データベースへのキーの挿入に関する問題が発生しました。状況は次のとおりです。

どちらもコレクションである 2 層のサブクラスを持つオブジェクトがあります。

オブジェクトを親と呼びましょう。これには子のコレクションがあり、このコレクション内のすべてのエンティティには独自のエンティティのコレクションがあります。次のようにマッピングされます。

親のマッピング<set>

<!--Parent-->
<set name="Collection"
     table="Table"
     cascade="all-delete-orphan"
     batch-size="15"
     inverse="true">
  <key column="ParentID"/>
  <one-to-many class="CollectionObject,CollectionObject-ns"/>
</set

CollectionObject のマッピング

<id name="ID" column="ID">
  <generator class="native"/>
</id>

<!-- property mappings-->
<property name="ParentID" column="ParentID" not-null="true"/>

<!--collection mapping-->
<set name="Collection"
     table="Table"
     cascade="all-delete-orphan"
     inverse="true"
     batch-size="15">
  <key column="ChildID"/>
  <one-to-many class="CollectionObject,CollectionObject-ns"/>
</set>

2 番目のコレクション内のオブジェクトのマッピング マッピングは、上記と同様です。想定されるシナリオは、親を保存すると、サブクラス/コレクションの保存がトリガーされるというものです。

たとえば、ID = 1 の親があり、親には 1 つのコレクションがあり、このコレクションには独自のコレクションが 1 つあります。

親を保存すると、親はデータベースから ID を取得します (ネイティブ SQL ID)。これで、最初のコレクションの ParentID プロパティに、Parent がデータベースから取得したばかりの ID が入力されます。また、コレクションのコレクションは、親が ID を取得したのと同じ方法で、子がデータベースから取得した ID で満たされた ChildID を取得する必要があります。

今起こっていることは(NHProfで作成されたSQLをチェックしました)すべてが独自のIDで挿入されますが、コレクションは親クラスのIDで満たされたキー列を取得しません。(代わりに、0 が挿入されるだけです)

要するに、私の質問は、マッピングに何を追加するのを忘れたのかということです。キー列は、私がすべきだと思うことをしませんか?

ここに何か追加するのを忘れた場合は、そう言ってください。喜んで追加情報を提供します。

アップデート

<many-to-one>問題は、子供にタグがないことに関係しているのではないかと思います。そこで、そのうちの 1 つを最初の子マッピングに追加しようとしました。私はこれを思いついた

   <many-to-one name="ParentID"
             class="Parent,Parent-ns"
             column="ParentID"
             not-null="true"/>

ただし、このセットアップでは次のエラーが発生します。 Exception occurred getter of Parent.ParentID

InnerException あり {"Object does not match target type."}

悲しいことに、このエラーでは、続行する場所についてのアイデアが得られません。

4

2 に答える 2

1

授業も見せていただけると助かります。Parent クラスに Parent 型の ParentID プロパティが実際にあることを確認しましたか?

<property name="ParentID" column="ParentID" not-null="true"/> 

あなたのマッピングから、それを多対一に置き換えましたか? 最後に、子オブジェクトに子オブジェクトのコレクションを持たせたい場合は、子オブジェクトにも多対 1 が必要になります。

<many-to-one name="CollectionObjectParent"
             class="CollectionObject,CollectionObject-ns"
             column="ChildID"
             not-null="true"/>
于 2010-03-09T18:38:11.693 に答える
0

悲しいことに、マッピングをいじってインターネットの半分を読んだ後、私はこれを解決できませんでした.

<Document>問題は、データベースから自分のキーを取得するシナリオに到達できず、<generator class="native"/>このキーを 1 回の呼び出しで基になるクラスの外部キー プロパティに挿入するという事実にありsession.Save()ます。

たとえば、私が望むシナリオの場合session.Save(document)

-- * 新しいドキュメントが検出されました -- * 新しい ID を取得します

-- * ドキュメントには外部キーを持つサブクラスがあります!
-- * 指定された外部キー プロパティに ID を挿入します(ここに問題があると思います)。

基礎となるすべてのクラスでこれを繰り返します。

しかし、私は回避策を思いつきました(これまでで最も醜いコードですが、仕事は完了します)私はこのくだらないコードを共有することにあまり興味がありませんが、ここを読んでいる人々に役立つかもしれません.

これを正しい方法で解決することをまだあきらめていませんが、当面はこれを行う必要があります。より良い方向への微調整のためにまだ開いています。

入ってくるがらくたコード!

    public void InsertDocument(Document document)
    {
        using (ISession session = NHibernateHelper.OpenSession())
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                 try
                 {                                          
                    IDocument document2 = new Document();
                    document2.Bodyregels = document.Bodyregels;
                    //for making the query a little neater
                    document.Bodyregels = null;                        

                    //lets get the elusive identity
                    session.Save(document);
                    session.Flush();

                    //reattach subclass and enter the id explicitly
                    document.Bodyregels = document2.Bodyregels;
                    foreach (DocumentBodyregel dbr in document.Bodyregels)
                    {
                        dbr.DocumentID = document.DocumentID;
                    }

                    //save it again, now with filled FK
                    session.Save(document);
                    session.Flush();

                    //now save the final subclass with FK's
                    foreach (DocumentBodyregel dbr in document.Bodyregels)
                    {
                        foreach (DocumentBodyregelWaarde dbrw in dbr.Waardes)
                        {
                            dbrw.RegelID = dbr.ID;
                            dbrw.DocumentID = document.DocumentID;
                        }
                    }

                    //and save the entire thing again (now with FK's)
                    session.Save(document);
                    transaction.Commit();
                }
                catch (Exception e)
                {
                    transaction.Rollback();
                    throw e;
                }
            }
        }
    }
于 2010-03-11T09:55:23.080 に答える