2012-03-14 60 views
3

我有一個用戶對象,其中一個屬性包含一個Photos屬性,它是IList類型。Nhibernate - 從屬表保存對象

SQL數據庫中的表由外鍵連接。即

表用戶{的userid長NOT NULL .......} 表UserPhoto {PHOTOID長NOT NULL,用戶ID不長空引用[用戶] .UserId ........}

所以你不能在沒有相應用戶行的userphoto中插入一行。

我想要做的就是在代碼中建立一個用戶對象,添加一個UserPhoto對象的Ilist(它必須包含一個空白的用戶ID,就像User對象一樣,因爲它沒有被保存,通過標識插入尚)創建

我的映射如下

<class name="User" table="[User]"> 
    <id name="UserId" column="Id"> 
     <generator class="identity" /> 
    </id> 
    <bag name="Photos" order-by="DisplayOrder asc" cascade="all">  
     <key column="UserId" /> 
     <one-to-many class="UserPhoto" /> 
    </bag> 
</class> 
<class name="UserPhoto" table="UserPhoto"> 
    <id name="PhotoId" column="Id"> 
     <generator class="identity" /> 
    </id> 
    <property name="UserId" /> 
</class> 

但是當我嘗試和保存與NHibernate Session.Save(用戶)的用戶對象,它拋出一個錯誤說外鍵約束失敗。所以,即時猜測它試圖插入用戶照片列表之前的用戶表,或其不設置新生成的用戶ID屬性的照片,並試圖用空的用戶ID保存它們。

您是否必須在映射中額外添加一些內容以顯示這是一個外鍵列及其應用,因此nhibernate知道如何以正確的順序插入相關行,以便在一次插入中完成此操作?

回答

1

試試這個:

<class name="User" table="[User]"> 
    <id name="UserId" column="Id"> 
     <generator class="identity" /> 
    </id> 
    <bag name="Photos" order-by="DisplayOrder asc" cascade="all" inverse="true">  
     <key column="UserId" /> 
     <one-to-many class="UserPhoto" /> 
    </bag> 
</class> 
<class name="UserPhoto" table="UserPhoto"> 
    <id name="PhotoId" column="Id"> 
     <generator class="identity" /> 
    </id> 
    <many-to-one name="User" property-ref="UserId" column="UserId"/> 
</class> 

逆=真正加入到照片袋

http://bchavez.bitarmory.com/archive/2007/10/06/nhibernate-and-inversetruefalse-attribute.aspx

也改變了用戶ID元素的多到一個用戶元素

+0

好的感謝您的鏈接,是有道理的。我仍然得到錯誤,但從你張貼的鏈接我得到的印象我需要在子女聲明映射?如果您在上面看到我的UserPhoto聲明,那麼只需將UserId映射爲屬性即可。這是問題嗎?在UserPhoto聲明中需要做什麼才能讓其瞭解FK關係?我試着在UserId上做一個簡單的Many to One,但它說:「來自表UserPhoto的關聯指的是一個未映射的類:System.Int32」 – NZJames 2012-03-14 15:33:07

+0

如果使用inverse = true,則需要在代碼中管理雙方的關係 - 請參閱我的答案進一步的細節。 – 2012-03-14 15:38:46

+0

我已經更新了答案。嘗試將UserId的屬性引用更改爲多對一的用戶映射,並將UserPhoto類更改爲 – reach4thelasers 2012-03-14 15:48:41

0

你需要將inverse="true"添加到包中,否則NHibernate將嘗試執行插入,然後進行更新:

<bag name="Photos" order-by="DisplayOrder asc" cascade="all" inverse="true">  
    <key column="UserId" /> 
    <one-to-many class="UserPhoto" /> 
</bag> 
0

你要麼需要在映射添加逆=「真」的照片集

<bag name="Photos" order-by="DisplayOrder asc" cascade="all" inverse="true"> 

,或者你將需要用戶ID列可爲空的照片表。

如果你做的第一選擇,你需要配置的對象自己之間的關係:

var user = new User(); 
var photo = new Photo(); 
photo.User = user; 
user.Photos.Add(photo); 

隨着逆=「真」集,NH將插入用戶,更新基於身份的用戶ID值,然後插入每張照片,將每個插入的用戶標識設置在照片表中。

如果沒有設置inverse =「true」,NH將插入帶有空userid的照片,爲插入的照片選擇所有照片ID,然後發出更新以設置後面的userid。這將導致生成額外的SQL語句。