8
votes

I'm trying to map a joined-subclass scenario using Fluent NHibernate. I have a class Entity defined in the namespace Core, and a class SubClass : Entity in the namespace SomeModule

Now I obviously don't want class Entity to know about its derived types, the SomeModules namespace references Core - not the other way around.

All the examples I've been able to find use something like:

public class EntityMap : ClassMap<Entity> {
    public EntityMap() {
        Id(x => x.Id)

        var subClassMap = JoinedSubClass<SubClass>("SubClassId", sub => sub.Map(x => x.Id));

        subClassMap.Map(x => x.SomeProperty)
        ...
    }
}

This simply won't work in my situation - I need something akin to the NHibernate xml mapping:

<joined-subclass name="SubClass" extends="Entity, Core" >
<key column="SubClassId" foreign-key="FK_KollegiumEntity"/>
<property name="Name" length="255" not-null="true" />
...
</joined-subclass>

Has anyone achieved this with Fluent NHibernate?

5

5 Answers

10
votes

I think the API has changed since this question was asked, but this works for me:

public class SomeSubclassMap : SubclassMap<SomeSubclass> {
    public SomeSubclassMap()
    {
        KeyColumn("SomeKeyColumnID");
        Map(x => x.SomeSubClassProperty);
        ...
    }
}

I believe KeyColumn is only required if it's different than 'Baseclassname_id'

Note: There should also be a ClassMap<SomeBaseClass> for the base class that SomeSubClass extends.

1
votes

Sorry missed your comment, found this

public class SubClassMap : JoinedSubClassPart< SubClass >
{
    public SubClassMap()
        : base("SubClassId")
    {
         Map(x => x.Name); 
         Map(x => x.SomeProperty); 
    }
}

Hope it helps if you haven't solved it already.

1
votes

Magnus (or Prise),

Did you figure out how to use that last example in the parent mapping class? This worked for me but I don't like instantiating the SubClassMap myself:

public class EntityMap : ClassMap<Entity> {
 public EntityMap() {
    Id(x => x.Id)
    AddPart(new SubClassMap()); // Adds the subclass mapping!
 }
}

public class SubClassMap : JoinedSubClassPart<SubClass>
{
    public SubClassMap()
        : base("SubClassId")
    {
         Map(x => x.Name); 
         Map(x => x.SomeProperty); 
    }
}

Which produced a query similar to:

SELECT
  this_.Id as Id2_2
  this_.Name as Name3_2
  this_.SomeProperty as SomeProperty3_2
FROM
  SubClass this_ inner join
    Entity this_1 on this_.Id=this_1.Id
0
votes

Magnus, I was having the exact same type of issue, and your suggestion sorted it.

The second parameter to JoinedSubClass takes a SubClassPart Action against your object of type SubT. Hence you only need to then map the additional fields on your subclassed object.

That previous example is mapping an Id, so i'm guessing thats a different id to the value the base and subclass join on, otherwise you'd start to see SqlParameterCollection errors being through.

0
votes

Hello did some thing like it a few days ago.

public class EntityMap : ClassMap<Entity> {
 public EntityMap() {
    Id(x => x.Id)

    JoinedSubClass<SubClass>("SubClassId", sub => { 
          sub.Map(x => x.Name); 
          sub.Map(x => x.SomeProperty); 
    });
 }
}

Hope it helps