2011-04-26 53 views
0

我有一個用戶實體具有IList屬性。對於 這個映射是這樣的:流利NHibernate和多個關鍵列

 HasMany(x => x.Forms) 
      .Cascade.None() 
      .AsBag().KeyColumn("Supervisor") 
      .Key(key => key.Not.Update()) 
      .PropertyRef("Email"); 

現在我在一個新的功能要求基本上是增加了一個 KeyColumn應該也將填充到這個屬性。實質上, 每個表格可以有一個「主管」和一個「備用」,我需要這個 屬性來填充任何表格,其中User.Email等於 (表格BELONG到用戶如果是User.Email == Form.Supervisor OR User.Email == Form.Alternate)。

有沒有辦法做到這一點?只需通過 增加另一個KeyColumn 規範簡單地覆蓋了前一個,並添加鍵Keys()方法似乎不允許多個鍵列像我 想......我正在尋找一種方式基本上告訴它這個 關係應該找到一個WHERE Superviser = Email OR Alternate = Email,但它似乎並不支持OR子句...

我的其他選項基本上重複此映射,但對於另一個屬性中的「替代」,然後猛然收集在一起我的消費代碼,但我想看看NHibernate是否足夠聰明,這是可能的...

有何建議?

回答

1

據我所知,不 - NHibernate不支持這種不尋常的連接類型。我會像你說的那樣完全接近你。使用兩個集合 - User.SupervisorFormsUser.AlternateForms,然後再合併它們,也許使用LINQ的Concat方法來做到這一點。你可以定義屬性爲你做這個串聯:

public virtual IEnumerable<Form> Forms 
{ 
    get { return SupervisorForms.Concat(AlternateForms); } 
} 

如果要加載一個完全初始化Forms集合User在一個往返到數據庫中,那麼你可以使用這種方法從NHibernate的文檔Improving Performace - Multi Query部分:

User user = s.CreateMultiQuery() 
    .Add("select u from User u left join fetch u.SupervisorForms where u.Id = :id") 
    .Add("select u from User u left join fetch u.AlternateForms where u.Id = :id") 
    .SetInt32("id", 123) 
    .UniqueResult<User>(); 

該代碼使用CreateMultiQuery()和HQL - 但是這種方法應該與您選擇的查詢配料語法的工作一樣:CreateMultiQuery()CreateMultiCriteria()Future()/FutureValue()

+0

這正是我最終做的事情,因爲我在NHibernate基地周圍扯皮沒有任何回報。違反了我希望儘可能限制SQL命中的條件(這基本上使它們翻倍),但是它的工作原理並沒有受到巨大的性能影響。 – 2011-04-28 04:07:24

+0

增加了有關在數據庫中往返一次的情況下預加載這兩個集合的信息。注意 - NHForge目前似乎處於關閉狀態,因此鏈接被破壞,但Google有一個[緩存的頁面副本](http://webcache.googleusercontent.com/search?q=cache:JC6X0f6JGfoJ:www.nhforge .ORG/DOC/NH/EN/index.html中+ nhforge +文檔和CD = 1&HL = EN&CT = clnk&GL = US&客戶=火狐-A&源= www.google.com)。 – 2011-04-28 15:31:13