开发者

Mapping interface or abstract class component

开发者 https://www.devze.com 2022-12-08 09:10 出处:网络
Please consider the following simple use case: public class Foo { public virtual int Id { get; protected set; }

Please consider the following simple use case:

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; }开发者_StackOverflow 
} 

And the fluent-nhibernate map class:

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

While running any query with configuration, I get the following exception:

NHibernate.InstantiationException: "Cannot instantiate abstract class or interface: NHMappingTest.IBar"

It seems that NHibernate tries to instantiate an IBar object instead of the Bar concrete class. How to let Fluent-NHibernate know which concrete class to instantiate when the property returns an interface or an abstract base class?

EDIT: Explicitly specify the type of component by writing Component<Bar> (as suggested by Sly) has no effect and causes the same exception to occur.

EDIT2: Thanks to vedklyv and Paul Batum: such a mapping should be soon is now possible.


I haven't tried this myself but i saw an example in the fluent nh source where the lambda is cast to the concrete class:

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

EDIT: Obviously that's exactly the same result as Sly's suggestion so that did no good. I tested it against the trunk version of fluent nh and it didn't work. It does work though if you use a many-to-one mapping:

  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

This was actually an easy fix. I have submitted a patch (link text) that makes Sly's solution to work.


Maybe this?

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


Here's a similar topic using the union-subclass approach, although the example does not use the fluent interface for the map:

Click for article...


Have not used the fluent NHibernate yet but seems to me what you are trying to do is map to an IUserType which you haven't told hibernate how to deal with. here is a useful example for defined usertypes in fluent.

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

0

精彩评论

暂无评论...
验证码 换一张
取 消