Объекты таблицы на подкласс с одинаковым идентификатором сталкиваются в кеше

Мне нужно сопоставить устаревшую таблицу с помощью Fluent NHibernate. У меня нет контроля над структурой таблицы.

Таблица выглядит так:

TypeId   ObjectId   Data
10       1          ...   //Cat 1
10       2          ...   //Cat 2
20       1          ...   //Dog 1
30       1          ...

Я пытаюсь отобразить это, используя структуру таблицы на подкласс, используя значение дискриминатора для TypeId,

public abstract class Animal
{
    public virtual int ObjectId { get; set; }
    public virtual string Data { get; set; }
}

public class AnimalMap : ClassMap<Animal>
{
    public AnimalMap()
    {
        Table("MyAnimals");
        Id(x => x.ObjectId);
        Map(x => x.Data);
        DiscriminateSubClassesOnColumn("TypeId")
            .AlwaysSelectWithValue();
    }
}

public class Cat : Animal
{
}

public class CatMap : SubclassMap<Cat>
{
    public CatMap()
    {
        DiscriminatorValue("10");
    }
}

public class Dog : Animal
{
}

public class DogMap : SubclassMap<Dog>
{
    public DogMap()
    {
        DiscriminatorValue("20");
    }
}

Проблема возникает, когда я пытаюсь загрузить Cat 1 после Dog 1, или наоборот.

var a = session.Get<Dog>(1); //Dog1
var b = session.Get<Cat>(1); //null

Если я выселу первого животного перед извлечением второго, это сработает.

var a = session.Get<Dog>(1); //Dog1
session.Evict(a);
var b = session.Get<Cat>(1); //Cat1

Когда я сопоставляю Dog и Cat к моему AnimalHome класс, я получаю следующее исключение:

Невозможно привести объект типа 'MyNamespace.Собака"набрать" MyNamespace.Кат.

Это приводит меня к мысли, что кэш не различает Dog а также Cat по их типам. Он просто думает об этом как Animal 1 и это Cat 1равняетсяDog 1,

Можно ли как-то заставить кеш учитывать фактический подкласс? В качестве альтернативы, если это невозможно для структуры таблицы на подкласс, как мне следует подходить к отображению этой таблицы?

1 ответ

Решение

Я решил это, отбросив дискриминатор. Where картографирование было более уместным в моем случае, так как на самом деле мне не нужно Dog или же Cat как Animal в моем коде. Я все еще сохраняю дублирование кода до минимума, наследуя Animalсопоставления.

public class AnimalMap<T> : ClassMap<T>
    where T : Animal
{
    public AnimalMap()
    {
        Table("MyAnimals");
        Id(x => x.ObjectId);
        Map(x => x.Data);
    }
}

public class CatMap : AnimalMap<Cat>
{
    public CatMap()
    {
        Where("TypeId = 10");
    }
}

Кеш теперь понимает, что Cat это не Dog,

Другие вопросы по тегам