2010-06-22 85 views
3

我已經弄清楚了很多關於nhibernate的內容,但這似乎是我不知道發生了什麼的最後一個障礙。所以這是問題。用NHibernate插入時保持引用完整性

我有一個基本的databas結構:

Shows: 
ID [Pk] 
CountryID [Fk] 
Name 

Countries: 
ID [Pk] 
Name 

CountryID具有從節目到國家表的主鍵一個鍵foriegn參考,各國已經填充了很少會更改預設值。

這裏是我的映射文件

public ShowMap() 
    { 
     Table("Shows"); 

     Id(x => x.ID); 
     Map(x => x.Name) 

     HasOne<Country>(x => x.CountryOrigin) 
      .Cascade.All() 
      .ForeignKey("CountryID"); 
    } 

    public CountryMap() 
    { 
     Table("Countries"); 

     Id(x => x.ID); 
     Map(x => x.Name); 
    } 

幾乎確保它是一個映射的問題,但是當我做一個插入到節目和我有連接到它的國家。 它試圖在數據庫中插入新的國家,而不是使用數據庫中已有的國家這似乎是主要問題。我不知道如何在數據庫中使用現有記錄的地方正確插入數據。

最後,這裏是一個例子,我試圖做一個插入不知道該怎麼做。

 using (var tx = _session.BeginTransaction()) 
     { 

      Show s1 = new Show(); 
      s1.CountryOrigin = new Country { ID = 2, Name = "Japan" }; 
      s1.Name = "Liar Game"; 

      _session.SaveOrUpdateCopy(s1); 
      tx.Commit(); 
      tx.Dispose(); 
      return true; 
     } 

所以,問題是我怎麼可以插入一個新的節目,有它在國家引用表中現有的記錄?


更新1我已經重新設計它使用有很多的關係,因爲我讀一個有一個可能是不正確的方式去。仍然有同樣的問題,這裏是代碼的變化。這些還反映了評論中的代碼更改。

插入代碼:

 using (var tx = _session.BeginTransaction()) 
     { 

      Show s1 = new Show(); 
      s1.CountryOrigin.Add(_session.Get<Country>(2)); 
      s1.Name = "Liar Game"; 

      _session.SaveOrUpdateCopy(s1); 
      tx.Commit(); 
      return true; 
     } 

映射:

public ShowMap() 
    { 
     Table("Shows"); 

     Id(x => x.ID); 
     Map(x => x.Name) 

     HasMany<Country>(x => x.CountryOrigin) 
      .KeyColumn("ID") 
      .Cascade.SaveUpdate(); 
    } 

    public CountryMap() 
    { 
     Table("Countries"); 

     Id(x => x.ID); 
     Map(x => x.Name); 
    } 

仍然得到像在一個評論中提到的無法插入空進CountryID。

更新2做一些位測試/調試:

  s1.CountryOrigin.Add(_session.Get<Country>(2)); 

請問什麼是應該做的,並得到了正確的國家,但問題發生在插入。所以這使我認爲這是更多的映射問題。

+0

只是一個迂腐點:你不需要'tx.Dispose()'。 'using'語句會爲你調用Dispose()。 – 2010-06-22 17:05:58

+0

即使我在tx.dispose之後返回true,也是如此嗎? – percent20 2010-06-22 17:09:11

+0

是的,它仍然會處置。 – 2010-06-22 17:34:52

回答

3

您在國家和節目之間擁有一對多的關係,並在多方面展示。所以國家應該使用映射References

public ShowMap() 
{ 
    Table("Shows"); 

    Id(x => x.ID); 
    Map(x => x.Name) 

    References(x => x.CountryOrigin, "CountryID"); 
} 
+0

謝謝,這是什麼解決它。而你對它的描述實際上使我更好地理解參考是如何工作的。好的簡短的解釋。謝謝。 – percent20 2010-06-22 18:26:10

0

您需要使用Session.Load讓你的國家目標:

s1.CountryOrigin = _session.Load<Country>(2); 

Session.Load說:「我知道,一個記錄與該ID數據庫存在我創建對象的代理,而不必去數據庫「。你也可以使用Session.Get,但這會創建一個額外的數據庫之旅。

+0

這就是我在讀的時候的想法,但是當我嘗試獲得的代碼時。 「無法將值NULL插入到'CountryID'列中作爲插入錯誤。這就是我很困惑的原因。儘管我認爲我找到了答案,而傳統的智慧說它應該起作用,但事實並非如此。 – percent20 2010-06-22 17:16:37