2009-10-10 114 views
4

請考慮下面簡單的例子:映射接口或抽象類成分

public class Foo 
{ 
    public virtual int Id { get; protected set; } 
    public virtual IBar Bar { get; set; } 
} 

public interface IBar 
{ 
    string Text { get; set; } 
} 

public class Bar : IBar 
{ 
    public virtual string Text { get; set; } 
} 

而流利,NHibernate的地圖類:

public class FooMap : ClassMap<Foo> 
{ 
    public FooMap() 
    { 
     Id(x => x.Id); 
     Component(x => x.Bar, m => 
     { 
      m.Map(x => x.Text); 
     }); 
    } 
} 

在運行與配置的任何查詢,我得到以下例外:

NHibernate.InstantiationException: 「不能實例化抽象類或接口:NHMappingTest.IBar」

看來,NHibernate的嘗試實例化對象IBar代替Bar具體類。如何讓Fluent-NHibernate知道在屬性返回接口或抽象基類時要實例化哪個具體類?

編輯:通過書寫明確指定組件的類型Component<Bar>(如Sly所建議的)沒有效果並導致發生相同的異常。

EDIT2:感謝vedklyv和保羅·巴圖姆:這種映射應該很快現在可能。

回答

4

我還沒試過此我自己,但我看到了在流暢的NH源的例子,其中拉姆達被轉換爲具體的類:

public class FooMap : ClassMap<Foo> 
{ 
    public FooMap() 
    { 
     Id(x => x.Id); 
     Component(x => (Bar) x.Bar, m => 
     { 
      m.Map(x => x.Text); 
     }); 
    } 
} 

編輯:顯然,這完全一樣的結果爲S1-1 y的建議,所以沒有好處。我測試了它與流利nh的主幹版本,並沒有奏效。它確實工作但如果你使用一個多到一的映射:

public class FooMap : ClassMap<Foo> 
    { 
    public FooMap() 
    { 
     Id(x => x.Id); 
     References<Bar>(x => x.Bar).Cascade.All(); 
    } 
    } 

    public class BarMap : ClassMap<Bar> 
    { 
    public BarMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.Text); 
    } 
    } 

UPDATE

這實際上是一個容易解決。我已經提交了一個補丁(link text),使Sly的解決方案能夠正常工作。

+0

(+1)感謝您向FNH開發團隊提交了補丁。 – 2009-11-09 14:03:57

1

也許這樣?

public FooMap() 
    { 
     Id(x => x.Id); 
     Component<Bar>(x => x.Bar, m => 
     { 
      m.Map(x => x.Text); 
     }); 
    } 
+0

不幸的是,它不起作用(同樣的例外)。似乎Fluent-NHibernate不使用泛型來推斷組件的類型。相反,它似乎使用反射來直接從lambda表達式參數獲取那條信息。 – 2009-10-13 08:36:56