2012-02-23 160 views
2

我有一個類,我想以兩種不同的方式映射到單個表,爲了隱私的原因。比方說,類看起來是這樣的:NHibernate:多個映射到單個表

class Person 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    // ... many other properties omitted ... 
} 

而相應的數據庫表如下所示:

create table Person 
(
    ID int not null, 
    RealName nvarchar(512) not null, 
    FakeName nvarchar(512) not null, 
    -- many other columns omitted 
) 

兩個映射我需要的是:

  • 名稱屬性真實姓名
  • 名稱屬性別名真實

所有其他屬性都應該被映射在這兩種情況下是相同的。我強烈希望不必重複這些其他屬性的映射。

我嘗試了幾種不同的方法,沒有運氣。使用<聯合子類>來隔離不同映射失敗並出現此錯誤:DuplicateMappingException:重複表映射人員。我可以創建兩個不同的數據庫視圖,並分別映射它們以避免重複的表映射錯誤,但這不是可取的。

使用「實體名稱」屬性來指定映射是誘人的,但記錄不完善,似乎有一些主要缺點:a)它需要我重複所有其他映射爲兩個實體,並且b )它與來自指向Person類的其他類的多對一>關係不兼容。

有沒有一個很好的方法來做到這一點,我失蹤了?

回答

0

您可以使用NHibernate的公式屬性相匹配的名稱屬性如下

<property name="Name" formula="(SELECT id,(CASE WHEN yourcondition then RealName else FakeName end) as Name FROM Person)"/> 

公式可以參考 - http://blog.khedan.com/2009/01/eager-loading-from-formula-in.html

+1

這是一個很好的建議,但我不認爲它適用於我,因爲我無法從SQL中測試以確定正確的映射。我需要控制應用程序層內的映射。 – brianberns 2012-02-23 19:10:27

0

即使我假設OP已經解決了他的問題在某些方面,我我想提出一個使用預測的解決方案。

基本上,你的數據訪問層(DAL)您選擇使用投影列表稍微複雜的方式來訪問你的數據,但回到取決於你的邏輯所需的FakePersonRealPerson類的實例。

這將是這個樣子:

FakePerson alias = null; 
var person = _session.QueryOver<Person>() 
    .SelectList(list => list 
     .Select(go => go.Id).WithAlias(() => alias.Id) 
     .Select(go => go.FakeName).WithAlias(() => alias.Name) // <- the trick 
     .Select(go => go.Other).WithAlias(() => alias.Other) 
    .TransformUsing(Transformers.AliasToBean<FakePerson>()); 

你仍然會映射您Person類這兩個屬性FakeNameRealName而且使protected和一個公共Name財產的人得到FakePersonRealPerson

我意識到你還是必須現在列出所有的屬性兩次,它已經從映射移動到了DAL。好吧,也許這可以幫助那裏的人,無論如何。