Question

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?

Was it helpful?

Solution

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top