2011-03-03 54 views
4

我有一個情侶表,例如:功能NHibernate - 映射一個屬性欄上的連接表

  • 產品{ID,名稱,ManufacturerId,...}
  • 製造商{ Id,Name,...}

我希望能夠在我的Product對象中包含ManufacturerName(而不必在我只需要名稱時加載整個Manufacturer行)。我的產品地圖看起來像...

Table("Product"); 
Id(x => x.Id, "Id"); 
Map(x => x.ProductName, "ProductName"); 
Map(x => x.ManufacturerId, "ManufacturerId"); 
References(x => x.Manufacturer, "ManufacturerId"); 

我需要添加什麼來填充我的Product對象的ManufacturerName屬性?我相信我需要進行某種Join()調用,但我無法弄清楚如何使用所有相關參數編寫它。它需要將當前表(產品)加入到製造商表中,在Product.ManufacturerId = Manufacturer.Id上,並抓住Manufacturer.Name列,在對象上填充ManufacturerName屬性。

回答

5

我想你可以使用formula動態檢索製造商名稱。這不是一個優雅的解決方案,我個人更喜歡使用一個單獨的sql視圖映射到一個新的實體(例如ProductExtra等),在那裏它只會​​查詢必要的列,但無論如何。在這裏,我們去:

  1. 的ManufacturerName屬性添加到產品類
  2. 添加映射線爲新的屬性您ProductMap:

    Table("Product"); 
    Id(x => x.Id, "Id"); 
    Map(x => x.ProductName, "ProductName"); 
    Map(x => x.ManufacturerId, "ManufacturerId"); 
    Map(x => x.ManufacturerName).Formula("(select m.ManufacturerName from Manufacturer m where m.Id = ManufacturerId)"); 
    
    References(x => x.Manufacturer, "ManufacturerId"); 
    

希望這有助於。

+0

這看起來像是一個很好的解決方案,除了DB是一個不支持select參數內的子查詢的oracle版本。 (呃)雖然 –

+0

非常感謝您接受這個答案,因爲它可能適用於後來尋找答案的99%的人。可悲的是,我在使用8年前的Oracle數據庫的1%中,這不起作用。 –

+0

啊..是的,我在Oracle 9中測試,所以這可能是爲什麼它在那裏工作。那麼,你仍然可以使用一個輔助sql視圖並將其映射到一個新的實體,該實體只包含一列的子集,然後使用它來代替常規產品,但我想它主要取決於場景。 –

1

NH連接非常棘手,並且需要您的模式可能不支持的事情。例如,連接表的主鍵與當前表的主鍵相匹配。它很像OneToOne映射,除了NH不會爲此產生明確的約束。由於在你的映射中情況並非如此(看起來像是多對一的引用),我懷疑你可以做一個明確的連接工作。

嘗試映射「直通」屬性:

public class Product 
{ 
    ... 

    public string ManufacturerName 
    { 
     get{return NHibernateUtil.IsInitialized(Manufacturer) 
        ? Manufacturer.Name : manufacturerName;} 
     set{if(NHibernateUtil.IsInitialized(Manufacturer)) 
      Manufacturer.Name = value 
      else 
      manufacturerName = value;} 
    } 
} 

... 

//In your mapping: 
Map(x => x.ManufacturerName, "ManufacturerName"); 

這將堅持規範化製造商的名稱到產品表作爲一個非標準化的領域。該字段也將存在於製造商表格中。當您檢索產品時,您從產品表中獲取名稱。製造商由於某種其他原因(或急切加載)而被延遲初始化後,您會從製造商表中獲得該名稱,這意味着您可以將製造商記錄的名稱保存到產品中。

+0

是的,這是多對一的。但是產品表實際上並沒有ManufacturerName,所以在製造商行初始化之前它會一直是空白的(或者只是在映射時會拋出一個錯誤)? –

+0

您必須將該字段添加到表中,或從可編輯視圖中提取產品記錄。這是ORM的缺點; NH只是希望你足夠的瞭解你已經映射的內容,當你要求它提供一條記錄時,將其全部拉回來,並且除了完全定製的查詢之外,並沒有給你許多選項來將連接的多表結果集從DB。 – KeithS

+0

不幸的是,以任何方式修改數據庫都是不可能的。看起來我必須處理每次單獨抓取整行的性能,或者處理過多的任何地方,建立一個我需要的所有ManufacturerIds的列表,並從中獲取所有ManufacturerId的名稱批量。感謝您的幫助。 –