映射接口或抽象类组件

时间:2009-10-10 19:23:04

标签: c# nhibernate fluent-nhibernate nhibernate-mapping

请考虑以下简单用例:

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和Paul Batum:这样的映射应该很快 现在可能。

4 个答案:

答案 0 :(得分:4)

我自己没有尝试过,但我在流利的nh源码中看到了一个示例,其中lambda被强制转换为具体类:

public class FooMap : ClassMap<Foo> 
{ 
    public FooMap() 
    { 
        Id(x => x.Id); 
        Component(x => (Bar) x.Bar, m => 
        { 
            m.Map(x => x.Text); 
        }); 
    } 
}
编辑:显然这与Sly的建议完全相同,所以没有好处。我测试了它与流畅的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);
    }
  }

<强>更新

这实际上是一个简单的解决方案。我已经提交了一个补丁(link text),使得Sly的解决方案能够正常运行。

答案 1 :(得分:1)

也许这个?

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

答案 2 :(得分:0)

这是使用union-subclass方法的类似主题,尽管该示例不使用地图的fluent接口:

Click for article...

答案 3 :(得分:0)

还没有使用流畅的NHibernate,但在我看来你要做的是映射到你没有告诉hibernate如何处理的IUserType。 这是一个有用的例子,用于流畅的定义的usertypes。

http://blog.jagregory.com/2009/01/11/fluent-nhibernate-auto-mapping-type-conventions/