i have the following scenario
public abstract class BaseClass
{
public virtual int Id {get; set};
public virtual string Name {get; set;}
}
public class Fir
It caused me headache to implement the "Table per Concrete Class" inheritance strategy with an abstract base class with nhibernate automapping. But I think, I've finally found a solution and want to share it with you. I also think, it's not added to the automapping docs, because it's maybe considered as a "weak" database design.
First here are some resources I found about this topic:
These resources basically describe how you need to do it:
// abstractBaseTypes is just a simple enumeration of base types
// model is the AutoPersistenceModel
abstractBaseTypes.ForEach(m => model = model.IncludeBase(m));
//sets the union subclass strategy for the known base model
model.Override<SuperType>(m => m.UseUnionSubclassForInheritanceMapping()))
public class AbstractRightEntryMappingOverride : IAutoMappingOverride<AbstractRightEntry>
{
public void Override(AutoMapping<AbstractRightEntry> mapping)
{
mapping.UseUnionSubclassForInheritanceMapping();
}
}
// You need to tell nhibernate where to find the overriden mappings.
// You simply can add the assemblies again.
modelAssemblies.ForEach(a => model = model.UseOverridesFromAssembly(a));
Since I haven't seen your mapping, let me provide mine. You could achieve this by doing like this
public class BaseClassMap:ClassMap<BaseClass>
{
public BaseClassMap()
{
/*
* Identity generator can't be native because subclass objects should be unique
* So use HiLo or Guid or other generators which will generate unique id on the child tables
*/
Id(x => x.Id).GeneratedBy.Guid();
Map(x => x.Name);
UseUnionSubclassForInheritanceMapping(); // This is important - uses union-subclass mappings for the derived classes
}
}
public class FirstSubClassMap : SubclassMap<FirstSubClass>
{
public FirstSubClassMap()
{
Table("FirstSubClassTable");
// Map properties for FirstSubClass
}
}
public class SecondSubClassMap : SubclassMap<SecondSubClass>
{
public SecondSubClassMap()
{
Table("SecondSubClassTable");
// Map properties for SecondSubClass
}
}