2011-04-18 66 views
9

當使用NHibernate時,如果我有一個實體具有唯一約束並且可以由該約束唯一標識,那麼將約束表示爲組合鍵還是具有獨立標識字段,並有一個複合獨特的約束?我一直在閱讀,認爲在NHibernate中使用組合鍵是「不好的」,如果它可以幫助,並且應該只在使用舊數據庫時才能使用。NHibernate複合關鍵與複合唯一約束

圖像設置如下:

class Book 
{ 
    public virtual int Id { get; protected set; } 
    public virtual string Author { get; set; } 
    public virtual IList<BookEdition> Editions { get; set; } //HasMany (one to many) 
} 

class BookEdition 
{ 
    public virtual string Title { get; set; } 
    public virtual string Language { get; set; } 
    public virtual int Edition { get; set; } 
} 

下面我們就針對地方對語言版的約束的BookEdition約束,即不可能有這本書的兩種版本在同一語言。任何版本也可以通過版本號和語言唯一標識。

在NHibernate中哪種方法更好?使用Language/Edition作爲複合標識或爲BookEdition引入一個Id變量,而是使用複合唯一約束?

回答

9

Surrorgate key(附加的Id變量)不僅在NHibernate中更好。自然鍵(這裏是語言和版本)的問題在於它們具有「商業」含義。業務需求會隨着時間的推移而變化,你將來必須改變自然的鑰匙,這可能會非常痛苦。另外你的SQL連接和條件會更復雜。

這可能是BookEdition的FNH映射覆合唯一約束:

Id(x => x.Id); 
    Map(x => x.Title); 
    Map(x => x.Language).UniqueKey("MyCompositeUniqueConstraint"); 
    Map(x => x.Edition).UniqueKey("MyCompositeUniqueConstraint"); 

順便說一句。不向客戶展示關鍵價值是一種好習慣。他們傾向於給他們分配一些商業含義,然後他們也想改變它們。

+0

這也是我正在考慮的映射。重寫Equals/GetHashCode以及使用自然鍵是否是個好主意?在我的基類中,我有一個Equals運算符,它對Id屬性起作用,但對於這種情況並不準確。我認爲使用「NaturalId()」也不可能有複合自然鍵。我不是很清楚自然身份證和獨特的約束之間的區別,冬眠條款.. – 2011-04-19 07:44:52

+0

國際海事組織獨特的約束(或關鍵)不在NH內臟中發揮任何作用。這只是指導如何創建數據庫。模式(在表上創建約束)。另一方面,主鍵(合成的,自然的,反向的 - 無所謂)是OR映射的基本概念。它說如何在數據庫表中唯一地找到一個實體。 – 2011-04-19 20:20:31

+0

嗯,似乎總是重寫Equals和GetHashCode總是好主意,特別是當涉及延遲加載和代理時(http://devlicio.us/blogs/billy_mccafferty/archive/2007/04/25/using-equals- GetHashCode的-effectively.aspx)。非常有趣,感謝您的問題,似乎我對NH還不瞭解:)。 – 2011-04-19 20:29:27