2009-04-17 33 views
0

本週我開始使用NHibernate(掙扎)。我有一個小應用程序與3表(我現在使用2)。表currency和表country這裏是映射文件。用NHibernate 2.0.1插入子表中

<class name="dataprovider.Country,dataprovider" table="country"> 
    <id name="CountryId" column="country_id" unsaved-value="0"> 
     <generator class="native"/> 
    </id> 
    <!--<bag name="BatchList" inverse="true" lazy="true" > 
     <key column="country_id" /> 
     <one-to-many class="Batch" /> 
    </bag> 
    <bag name="PrinterList" inverse="true" lazy="true" > 
     <key column="country_id" /> 
     <one-to-many class="Printer" /> 
    </bag>--> 
    <many-to-one name="CurrencyId" column="currency_id" class="Currency" cascade="save-update"/> 
    <!--<property column="currency_id" name="Currency_Id"/>--> 
    <property column="name" name="Name"/> 
    <property column="region" name="Region" /> 
    <property column="comments" name="Comments"/> 
</class> 

貨幣映射文件:

<class name="dataprovider.Currency, dataprovider" table="currency"> 
    <id name="CurrencyId" column="currency_id" > 
     <generator class="native"/> 
    </id> 
    <bag name="CountryList" inverse="true" lazy="true" > 
     <key column="currency_id" /> 
     <one-to-many class="Country" /> 
    </bag> 
    <!--<bag name="DenominationList" inverse="true" lazy="true" > 
     <key column="currency_id" /> 
     <one-to-many class="Denomination" /> 
    </bag>--> 
    <property column="name" name="Name"/> 
    <property column="authorizer" name="Authorizer" /> 
    <property column="date_created" name="DateCreated" type="DateTime" not-null="true" /> 
    <property column="comments" name="Comments" /> 

的多對一的關係那country保持創建類型Currencycountry持久類的屬性。現在,雖然我的測試can_add_currencycan_add_country成功(我導出架構),但在字段currency_id的表country中的表值爲空。

下面是測試代碼:

[Test] 
    public void can_add_new_country() 
    { 
     CountryManager cm = new CountryManager(); 

     Country country = new Country(); 
     //country.CurrencyId = CurrencyManager.GetCurrencyById(1); 
     country.CurrencyId = new CurrencyManager().GetCurrencyById(1); 
     country.Name = "POUND"; 
     country.Region = "ENGLAND"; 
     country.Comments = "the comment"; 

     cm.Add(country); 

     using(ISession session = _sessionFactory.OpenSession()) 
     { 
      Country fromdb = session.Get<Country>(country.CountryId); 
      Assert.IsNotNull(fromdb); 
      Assert.AreNotSame(fromdb, country); 
     } 
    } 

    public Currency GetCurrencyById(int currency_id) 
    {//GetCurrencyById from CurrencyManger class 
     try 
     { 
      using(ISession session = NHibernateHelper.OpenSession()) 
      { 
       return session.Get<Currency>(currency_id); 

      } 
     } catch (Exception ex) 
     { 
      return null; 
     } 
    } 

的問題是:如何插入到表中的國家,從表中貨幣現有currency_id的currency_id?

你們是怎麼做到的?我被嚴重卡住了,一個爲期兩天的小型項目現在正在一週內帶走我。

回答

0

請在您的bag name="CountryList"上設置cascade="save-update"。如果這不起作用,可以發佈代碼CountryManager.Add()以查看保存是如何發生的。

在回答你的第二個問題,如果我理解正確,這是對待如何NHibernate的映射集合:

你映射的集合作爲懶惰,所以加載對象將負荷所有的元素同時收集。相反,當你第一次訪問集合時,NHibernate將查詢數據庫來填充集合並返回它。所以,當你第一次做這樣的事情:

var countries = currency.CountryList; 

foreach (Country country in currency.CountryList) 

NHibernate的會悄悄執行類似的查詢:

SELECT * FROM country WHERE currency_id = ? 

,然後建立國家對象的集合返回(並緩存以便查詢不再運行)。

基本上,通過映射文件,你已經告訴NHibernate的所有關於你的兩個實體(國家和貨幣)以及它們是如何相關的,所以它知道如何構建查詢來訪問數據。同樣,它跟蹤的是什麼集合中,所以當您添加或刪除的項目,它可以比較有什麼改變並執行相應的插入或刪除語句。

因此,使用由NHibernate的映射集合的方式是,就像你用普通的.NET集合使用它們。根據您的意願添加和刪除項目。只是當你完成後,一定要告訴NHibernate的堅持您對數據庫所做的更改,無論是通過添加/上刪除或(如果設置級聯,就像你有)簡單的通話session.Save()每一個項目叫session.Save()session.Delete()包含集合的父對象。

0

我的級聯是相當的這一邊:

<many-to-one name="CurrencyId" column="currency_id" class="Currency" cascade="save-update"/> 

後,我改變了它,它是在沒有首先,即使我重新生成解決方案的工作。然後我做了Currency_Test類的另一個測試:can_get_currency_by_id其中調用相同的函數GetCurrncyById,我可以有一個對象,而從can_add_new_country相同的函數返回null。

然後我意識到Country_Test [Setup]Currency_Test的ExportSchema沒有按時爲can_add_new_product創建貨幣對象。這就是爲什麼它返回空對象。

現在不要濫用;但你能告訴我如何使用IList<Counrty>CountryList?我不知道我是否把它放好。根據我的理解,它應該使用相同的currency(currency_id reference)存儲所有country對象。 NHibernate如何做到這一點?

+0

我更新了我的答案,希望它能回答你所問的問題。 – 2009-04-20 18:50:09