I'm trying to automap a simple inheritance hierarchy with Fluent Nhibernate, and I need to have a slightly different name for each table than its class (underscores instead of Pascal case). This seems like an obvious place to use conventions. I also want to use the table-per-subclass strategy, but the combination seems to be causing me an issue: the convention is only applied to the base class of the hierarchy.
Here's my automapping:
AutoMap
.AssemblyOf<BaseRule>()
.IncludeBase<BaseRule>() // "BaseRule" is an abstract class
.Conventions.Add( DefaultCascade.All() )
.Conventions.Add<OracleTableNameConvention>()
How I want my classes mapped (class name -> table name):
abstract class BaseRule -> Base_Rule
class NumberRule : BaseRule -> Number_Rule
class PatternStringRule : BaseRule -> Pattern_String_Rule
What I'm actually getting:
BaseRule -> Base_Rule
NumberRule -> NumberRule
PatternStringRule -> PatternStringRule
As you can see, only the base class is actually being changed. Here's my existing convention, just so you can see how I'm defining it:
public class OracleTableNameConvention : IClassConvention
{
public void Apply(IClassInstance instance)
{
string fixedName = instance.EntityType.Name.ToUnderscoredNaming();
instance.Table(fixedName);
}
}
I've also looked into the ISubclassConvention
interface, and can see no way in there to adjust the name of the table (which makes enough sense, subclasses aren't always in their own table).
If I delete the IncludeBase
line from my automapping, the names become what I want, except it becomes table-per-concrete-class. I want to use table-per-subclass, leaving all the common data in one shared base table.
I can add overrides for each name, and I will if I have to, but I'd rather not.
It seems like this should be an obviously supported behavior. How can I have the naming convention apply to each table in the hierarchy, without going to table-per-concrete-class?
As soon as I posted this question, I figured it out.
IJoinedSubclassConvention
is the interface I needed to implement.
public class OracleSubClassConvention : IJoinedSubclassConvention
{
public void Apply(IJoinedSubclassInstance instance)
{
string fixedName = instance.EntityType.Name.ToUnderscoredNaming();
instance.Table(fixedName);
}
}
I found it by looking for anything that had a method Table(string)
.