Fluent NHibernate - Mapping a multi level class hierarchy
I have a legacy database that uses a table per class hierarchy inheritance strategy that uses two database columns as discriminators, usetype and formattype. UseType gives you the top level, formattype the second.
Essentially I would like to be able to populate a class hierarchy like:
public abstract class Unknown {}
public abstract class Animal : Unknown { }
public class Lion : Animal {}
public class Lamb : Animal {}
public class Mineral : Unknown { }
public abstract class Vegetable : Unknown {}
public class Rose : Vegetable { }
public class Cabbage : Vegetable {}
From data like:
| UseType开发者_运维技巧 | FormatType | -------------------------- | Animal | Lion | | Animal | Lamb | | Mineral | null | | Vegetable | Rose | | Vegetable | Cabbage |
I thought I could user Fluent mappings like:
public sealed class UnknownMap : ClassMap<Unknown>
{
public UnknownMap()
{
DiscriminateSubClassesOnColumn("UseType");
}
}
public sealed class AnimalMap : SubclassMap<Animal>
{
public AnimalMap()
{
DiscriminatorValue("Animal");
DiscriminateSubClassesOnColumn("FormatType");
}
}
public sealed class LionMap : SubclassMap<Lion>
{
public LionMap()
{
DiscriminatorValue("Lion");
}
}
public sealed class LambMap : SubclassMap<Lamb>
{
public LambMap()
{
DiscriminatorValue("Lamb");
}
}
public sealed class MineralMap : SubclassMap<Mineral>
{
public MineralMap()
{
DiscriminatorValue("Mineral");
}
}
public sealed class VegetableMap : SubclassMap<Vegetable>
{
public VegetableMap()
{
DiscriminatorValue("Vegetable");
DiscriminateSubClassesOnColumn("FormatType");
}
}
public sealed class RoseMap : SubclassMap<Rose>
{
public RoseMap()
{
DiscriminatorValue("Rose");
}
}
public sealed class CabbageMap : SubclassMap<Cabbage>
{
public CabbageMap()
{
DiscriminatorValue("Cabbage");
}
}
But unfortunately DiscriminateSubClassesOnColumn isn't supported in SubclassMap.
According to the Fluent NHibernate Wiki, multi column discriminators are supported through the use of a custom sql statement.
Unfortunately, I have to support a rather large number of subclasses, and I'd really prefer to use something that's compiled with the code. After all, that's why I'm using Fluent NHibernate in the first place.
2 options for using string concatenation come to my mind:
generate a storedProcedure for stringconcatenation which can be reimplemented in each DB-System and use a formula to call it
make the classmap
UnknownMap
database awarepublic UnknownMap() { string formula; switch (Configuration.GetDbType()) { case DBType.SQLServer: formula = "GROUP_CONCAT(UseType, FormatType´)"; break; ... } DiscriminateSubClassesOnColumn("") .Formula(formula); }
精彩评论