Skip navigation

Monthly Archives: March 2011

I just wanted to quickly throw this out there because I had a really hard time finding any information out there on this issue.  The scenario I have is a base abstract class which contains a handful of properties.  There are three types which extend this class and add their own relationships.

The problem I ran into is that by default the auto mapper for Fluent automatically uses the type names as the discriminator to determine which type should be loaded.  What this means is the column in the database must be a varchar.  I think it is pretty obnoxious to have the full type of your class in every single row.  What I want is to use an enum to determine which type is used, and have it stored as an integer in the database.  You’d think this would be a pretty simple and well documented use case; it is not.

First off, you’ll need to create an auto mapping override for the parent class:

public class ParentMap : IAutoMappingOverride {
    public void Override(AutoMapping mapping) {
        mapping.DiscriminateSubClassesOnColumn("Type", 0);
    }
}

Regardless, I figured out how to do what I wanted to do.  In your auto mapping configuration class, you’ll need to tell the auto mapper to ignore the types which extend the abstract base class, like so:

public override bool ShouldMap(System.Type type) {
	return type != typeof(ChildType1) && type != typeof(ChildType2) && type != typeof(ChildType3);
}

Next, you need to create your own SubclassMap which manually maps all of the properties specific to the child class. Just to be clear, you do not have to map any of the properties defined in the parent class. These properties should be handled by the auto mapper (and if you need to modify the mappings you should create an Auto Mapping Override.

class ChildType1Map : SubclassMap {
    public ChildType1Map() {
        this.DiscriminatorValue((int)MyEnum.ChildType1);
        this.References(x => x.AnotherThing);
        this.Map(x => x.Name);
    }
}

The important part here is the call to DiscriminatorValue. This is where you instruct NHibernate what the value of the discriminator column will be for this type. Do the same for your other entities that extend the parent class. In order to get Fluent to pick up on these mapping files you’ll need to register them in your AutoPersistenceModel:

model.Add(typeof(ResourceFolderMap));

That should be all it takes. Hopefully this saves someone the hours I spent researching this.