2017-01-03 41 views
0

我需要使用Fluent NHibernate映射旧式表。我无法控制表格结构。具有相同ID的每个子类对象在高速缓存中发生冲突

表看起来是这样的:

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

的问题,当我尝试Dog 1后加载Cat 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 

当我映射既是DogCatAnimalHome类,我得到以下异常:

无法投类型的对象myNameSpace对象。 '键入 'MyNamespace。 Cat'。

这使我相信缓存不会区分它们的类型DogCat。它只是认为它为Animal 1而且Cat 1等于Dog 1

我可以以某种方式使缓存考虑实际的子类吗? 另外,如果这不可能与每个子类的表结构,我该如何处理这个表的映射?

回答

1

我通过放弃鉴别器解决了这个问题。 A Where映射更适合我的情况,因为我实际上并不需要在我的代码中将DogCat视为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

相关问题