0

我需要使用 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

当我将 aDog和 a都映射Cat到我的AnimalHome班级时,我得到以下异常:

无法转换类型为“MyNamespace”的对象。Dog ' 输入 'MyNamespace. '。

这让我相信缓存并没有区分Dog它们Cat的类型。它只是认为它是Animal 1and that Cat 1equalsDog 1

我可以以某种方式让缓存考虑实际的子类吗?或者,如果这对于每个子类的表结构是不可能的,我应该如何映射这个表?

4

1 回答 1

1

我通过放弃鉴别器解决了这个问题。在Where我的情况下,映射更合适,因为我实际上不需要在我的代码中将DogorCat视为 an AnimalAnimal我仍然通过继承-related 映射将代码重复降至最低。

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

缓存现在知道 aCat不是 a Dog

于 2017-01-04T09:57:30.423 回答