Свободный NHibernate - Отображение многоуровневой иерархии классов - PullRequest
1 голос
/ 19 июля 2011

У меня есть устаревшая база данных, в которой используется стратегия наследования иерархии таблиц для каждого класса, в которой используются два столбца базы данных в качестве дискриминаторов: usetype и formattype. UseType дает вам верхний уровень, второй формат типа.

По сути, я хотел бы иметь возможность заполнить иерархию классов, например:

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 {}

По данным типа:

| UseType   | FormatType |
--------------------------
| Animal    | Lion       |
| Animal    | Lamb       |
| Mineral   | null       |
| Vegetable | Rose       |
| Vegetable | Cabbage    |

Я думал, что смогу использовать отображения Fluent как:

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");
    }
}

Но, к сожалению, DiscriminateSubClassesOnColumn не поддерживается в SubclassMap.

Согласно Fluent NHibernate Wiki , многостолбцовые дискриминаторы поддерживаются с помощью пользовательского оператора SQL.

К сожалению, я должен поддерживать довольно большое количество подклассов, и я действительно предпочел бы использовать то, что скомпилировано с кодом. В конце концов, именно поэтому я использую Fluent NHibernate.

1 Ответ

1 голос
/ 19 июля 2011

2 варианта использования конкатенации строк приходят мне на ум:

  • создать хранимую процедуру для конкатенации строк, которую можно переопределить в каждой DB-системе, и использовать формулу для ее вызова

  • сделать карту классов UnknownMap базой данных

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