0

在我的映射有一點變化( see my other question about cascade-delete for reasons)後,我嘗試插入一個全新的對象及其所有子類。nhibernate映射不保存/插入插入的子類的鍵

之後出現另一個問題,將密鑰插入到數據庫中的問題。情況如下:

我有一個對象與2層的子類,這兩個集合。

讓我們調用對象Parent,這個對象有一個childs集合,並且這個集合中的每個實體都有自己的實體集合。其中映射如下。其<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號集合中的對象的映射映射

家長測繪以上是TOT他相似。 設想的情況是,我保存父,這將觸發子類/集合的保存。

例如我有ID = 1的父母,父母填充1個收藏,並且此收藏擁有1個收藏。

因此,我保存父,父從數據庫中獲取一個ID(本機sql身份)。現在第一個集合應該得到它的ParentID屬性,它填充了Parent從數據庫中獲得的ID。並且集合的集合應該使用ChildID填充Child從數據庫中獲取的ID,方法與Parent獲得其ID相同。

現在發生的事情是(我在NHProf中檢查了創建的SQL)一切都被插入,並帶有它自己的ID,但是集合沒有得到填充其父類ID的keycolumn。 (而不是它插入0)

所以我的問題歸結爲,我忘了添加到我的映射導致發生什麼?關鍵列沒有做我認爲應該做的事情嗎?

如果我忘記在這裏添加任何東西,請說出來。我很樂意提供更多信息。

更新

我認爲這個問題可能與不具有<many-to-one>標籤孩子的做。所以我試圖將其中的一個添加到第一個子映射中。我想出了這

<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."}

可悲的是,這個錯誤並沒有給我的地方繼續任何想法。

回答

1

我認爲如果您可以向我們展示您的課程也會有所幫助。你檢查你的父類真有型家長的PARENTID財產,還我假定你現在已經從你的映射刪除

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

,並與多到一個替代它?最後,如果你希望你的孩子對象有子對象的集合,那麼子對象還需要一個多到一個

<many-to-one name="CollectionObjectParent" 
      class="CollectionObject,CollectionObject-ns" 
      column="ChildID" 
      not-null="true"/> 
+0

Hey Gareth, 林不知道我是否完全理解你。父應該有一個名爲ParentID的屬性,它的類型是? 這樣Parent PARENTID {獲得;設置;} 目前PARENTID僅僅是一個整數,即時通訊困惑現在:) – marn 2010-03-10 11:13:21

+0

而不是增加至DocumentID的引用您需要引用實際的父對象文件。見鏈接,就如何處理父子情況的信息 - 希望它有助於http://www.nhforge.org/doc/nh/en/index.html#example-parentchild – Gareth 2010-03-10 16:34:47

+0

我讀過接近谷底的文檔,以20倍但我仍然缺少一些我很擔心的事情。我在下面發佈了一個解決方法,它現在必須做,但仍然可以提供建議。目前我正在觀看http://www.summerofnhibernate.com/會話。希望對我來說更清楚些。 – marn 2010-03-11 09:58:29

0

可悲的是,與映射玩耍和閱讀槽一半的互聯網後,我沒有能夠解決這個問題。

問題在於這樣一個事實,我不能讓該<Document>從數據庫<generator class="native"/>得到他的鑰匙在這之後再將其插入鑰匙插入其底層階級的外鍵的屬性,只是一個session.Save()電話裏面的場景。

例如對於方案我想session.Save(document)

- *新文件檢測 - *獲得新的身份

- *文檔有子類有外鍵吧!
- *插入idenity到外鍵的屬性指定的(猜測,這裏存在的問題)

,並與所有基本類重複這一點。

,但我卻想出了一個解決辦法(最醜陋的代碼以往,但它能夠完成任務),我不是真正進入代碼共享這個討厭的,但它也許會幫助人們閱讀這裏。

我還沒有放棄對解決這個正確的方法,但目前這所要做的。斯蒂爾打開一個更好的方向推動。

進入垃圾代碼!

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