我需要使用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
课程时,我收到以下异常:
无法投射&#39; MyNamespace类型的对象。狗&#39;输入 &#39; myNameSpace对象的猫&#39;
这让我相信缓存并没有区分Dog
和Cat
的类型。它只是将其视为Animal 1
而 Cat 1
等于Dog 1
。
我可以以某种方式使缓存考虑实际的子类吗? 或者,如果每个子类的表结构不可能实现这一点,那么我该如何处理这个表的映射?
答案 0 :(得分: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
。