Объекты таблицы на подкласс с одинаковым идентификатором сталкиваются в кеше
Мне нужно сопоставить устаревшую таблицу с помощью 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
,