2

我正在尝试使用 Fluent Nhibernate 自动映射一个简单的继承层次结构,并且我需要为每个表使用与其类稍有不同的名称(下划线而不是 Pascal 大小写)。这似乎是一个使用约定的明显地方。我也想使用 table-per-subclass 策略,但这种组合似乎给我带来了一个问题:该约定仅适用于层次结构的基类。

这是我的自动映射:

AutoMap
    .AssemblyOf<BaseRule>()
    .IncludeBase<BaseRule>() // "BaseRule" is an abstract class
    .Conventions.Add( DefaultCascade.All() )
    .Conventions.Add<OracleTableNameConvention>()

我希望我的类如何映射(类名-> 表名):

  abstract class BaseRule -> Base_Rule
  class NumberRule : BaseRule -> Number_Rule
  class PatternStringRule : BaseRule -> Pattern_String_Rule

我实际得到的是:

  BaseRule -> Base_Rule
  NumberRule -> NumberRule
  PatternStringRule -> PatternStringRule

如您所见,实际上只更改了基类。这是我现有的约定,以便您可以看到我是如何定义它的:

public class OracleTableNameConvention : IClassConvention
{
    public void Apply(IClassInstance instance)
    {
        string fixedName = instance.EntityType.Name.ToUnderscoredNaming();
        instance.Table(fixedName);
    }
}

我还查看了ISubclassConvention界面,并且看不到那里可以调整表的名称(这很有意义,子类并不总是在它们自己的表中)。

如果我从我的自动映射中删除该IncludeBase行,名称就会变成我想要的,除了它变成每个具体类的表。我想使用每个子类的表,将所有公共数据留在一个共享基表中。

我可以为每个名称添加覆盖,如果必须,我会添加,但我宁愿不这样做。

看起来这应该是一个明显受支持的行为。如何将命名约定应用于层次结构中的每个表,而无需逐个具体类进行表?

4

1 回答 1

4

当我发布这个问题时,我想通了。

IJoinedSubclassConvention是我需要实现的接口。

public class OracleSubClassConvention : IJoinedSubclassConvention
{
    public void Apply(IJoinedSubclassInstance instance)
    {
        string fixedName = instance.EntityType.Name.ToUnderscoredNaming();
        instance.Table(fixedName);
    }
}

我通过寻找任何有方法的东西找到了它Table(string)

于 2012-06-04T22:00:01.283 回答