开发者

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 aware

    public UnknownMap()
    {
        string formula;
        switch (Configuration.GetDbType())
        {
            case DBType.SQLServer:
                formula = "GROUP_CONCAT(UseType, FormatType´)";
                break;
            ...
        }
    
        DiscriminateSubClassesOnColumn("")
            .Formula(formula);
    }
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜