2009-04-21 59 views
3

我有一個表格有與Campaigns Table相關的CampaignID列的Donations。如果Campaign未用於此捐贈,我需要在CampaignID列中插入0而不是Null。NHibernate保存0到多對一的列而不是空的

我從捐款表映射是這樣的:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true"> 
    <class name="Donation,Entities" lazy="true" table="Donations" dynamic-update="true" > 
     <id name="DonationID" column="PledgeID" type="Int64"> 
      <generator class="native" /> 
     </id> 
     <many-to-one name="FundraisingCampaign" class="Campaign, Entities" column="CampaignID" lazy="proxy" not-found="ignore" cascade="none" /> 

之前,我保存到數據庫中我檢查,看看是否活動實體上我的捐贈實體爲空。如果是這樣,那麼我將它設置爲一個新的活動實體,並像這樣設置CampaignID = 0。

if (null == donation.FundraisingCampaign) 
    { 
     donation.FundraisingCampaign = new Campaign() {CampaignID = 0}; 
    } 

問題是我得到一個ErrorMessage「對象引用未保存的瞬態實例 - 在沖洗前保存瞬態實例。」當試圖保存。

我不明白爲什麼它關心我的Campaign對象而不是CampaignID,因爲我有cascade =「none」它不應該嘗試將任何內容保存到Campaign表中。

我被當前系統強制設置爲0而不是Null,因此保存Null不是一個選項。

回答

3

嘗試從DB中加載其DB標識爲0的Campaign對象。它將成爲一個完全持久的對象。然後,您應該能夠設置並堅持捐贈。

如果此方法有效,您需要更改Campaign對象的ID屬性映射。 Nh無法確定您在此創建的瞬態活動對象:

new Campaign() {CampaignID = 0}; 

實際上是一個分離對象。你應該做的是在你的映射-1中添加一個'未保存的值'。現在,Nh可以分辨您的有效分離廣告系列與數據庫身份ID爲0之間的差異,以及Ids爲-1的臨時新廣告系列。然後請記住將新創建的廣告系列的ID設置爲-1。

+0

我我未保存值設置爲-1,更新了所有我的代碼現在設置的CampaignID爲-1,以創建一個新的。我現在在我的CampaignID中有0個而不是Null。感謝諾埃爾。 – Adam 2009-04-21 21:37:45

2
  1. NHibernate通過檢查主鍵知道實體是否已經存儲。如果它是0,則不存儲。您可以在映射中更改此行爲。
  2. 如果您嘗試保存實體,則所有引用實體都必須級聯或已存儲。這對NHibernate取得外鍵很重要。它不能用外鍵指向你的內存,它必須在數據庫中,所以它必須被存儲。如果不是這種情況,你會得到你有的例外信息。

有了這些信息,你應該明白爲什麼你有這個問題。

是否使用自動計數器生成CampaignID?然後它無論如何都不起作用。 (您不能在應用程序中設置ID。)除非您將Campaign存儲爲CampaignID = 0(請參閱下文)。

您可以使CampaignID成爲空值int,然後未保存的值默認爲空。

請注意,您在CampaignID = 0的數據庫中獲得了Campaign。這是一個「空對象」。您需要存儲它,例如在安裝數據庫之後。

如果你想避免null對象,你會遇到麻煩。 NHibernate概念上不允許你訪問外鍵,它爲你管理它。你可能會做一些技巧(例如在攔截器中),但我認爲這是不值得的麻煩。你還必須確保沒有外鍵約束,這也不好。