1

看起來一個常見的情況對我說:我有兩個表: 文件: DID(PK,INT),DNAME(VARCHAR)如何將相關的表映射與流利,NHibernate的無主鍵

和document_options : DID(INT),oType(INT),oValue(VARCHAR)

我想有一個屬性選項一個類文件(DocumentOption類的List)

由於document_options沒有PK我不能使用HasMany,並且來自該表的行似乎不像「真實」的實體...

我明白的方式來生成文件選項的自動編號鍵,用的hasMany地圖,或者可能創建一個複合的ID,但我想知道是否有一個更好的選擇,我不知道。

回答

2

在這種情況下,DocumentOptions是一個值對象,因爲它有自己的沒有身份,並且具有其所屬的文檔之外沒有任何意義。所以,你會用Component映射集合屬性的值對象。

public class Document : Entity // don't worry about Entity; it's a base type I created that contains the Id property 
{ 
    public virtual string Name { get; set; } 

    public virtual IList<DocumentOptions> Options { get; protected set; } 

    public Document() 
    { 
     Options = new List<DocumentOptions>(); 
    } 
} 

public class DocumentOptions 
{ 
    public virtual int Type { get; set; } 

    public virtual string Value { get; set; } 
} 

和映射:

public DocumentMap() 
{ 
    Table("documents"); 

    Id(c => c.Id) 
     .Column("dId") 
     .GeneratedBy.HiLo("10"); 

    Map(c => c.Name) 
     .Column("dName"); 

    HasMany(c => c.Options) 
     .Component(c => 
         { 
          c.Map(c2 => c2.Value).Column("oValue"); 
          c.Map(c2 => c2.Type).Column("oType"); 
         }) 
     .Table("document_options") 
     .KeyColumn("dId") 
     .Cascade.AllDeleteOrphan(); 

} 
+0

謝謝,經過大量的閱讀後,我想出了一個非常相似的答案,只有它使用沒什麼Id和可能其他一些瑣事=) – Spikolynn

+0

事實上,也有一些類似的方法。隨着忘記指定表名外,我試圖讓映射,你在你的問題中指定精確匹配的表。 – HackedByChinese

+0

你介意告訴我,你爲什麼用「保護套」,創造的新選項列表在構造函數中還好嗎?我的解決方案似乎工作,但你似乎比我更瞭解它。 – Spikolynn

0

如果我理解正確的話,我不得不映射選項的組件列表:

HasMany(x => x.DocumentOptions) 
    .Table("document_options") 
    .KeyColumn("dID") 
    .Component(c => { 
      c.Map(x => x.Option, "oID"); 
      c.Map(x => x.Value, "oValue"); 
    }) 
    .Fetch.Subselect(); //This type of join isn't strictly needed, is used for SQL optimization 

類FYI:

public class Options { 
    public virtual int Option { get; set; } 
    public virtual int Value { get; set; } 
} 

public class Document { 
    public virtual int ID { get; set; } 
    public virtual String Name { get; set; } 
    public virtual IList<DocumentOption> DocumentOptions { get; set; } 
}