请考虑以下简单用例:
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:这样的映射应该很快 现在可能。
答案 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接口:
答案 3 :(得分:0)
还没有使用流畅的NHibernate,但在我看来你要做的是映射到你没有告诉hibernate如何处理的IUserType。 这是一个有用的例子,用于流畅的定义的usertypes。
http://blog.jagregory.com/2009/01/11/fluent-nhibernate-auto-mapping-type-conventions/