0

Fluent NHibernateを使用して従来のテーブルをマップする必要があります。私はテーブル構造を支配していません。同じIDを持つサブテーブルごとのオブジェクトがキャッシュ内で衝突する

テーブルは次のようになります。私はこのTypeIdための識別値を使用して、テーブルあたりのサブクラス構造を使用してマップしようとしています

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

。私はDog 1、またはその逆の後Cat 1をロードしようとすると、

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

問題が発生します。

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

私が第2の動物を取り出す前に最初の動物を追い払うと、それは機能します。

型「MYNAMESPACEのオブジェクトをキャストすることができません:

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

私は私のAnimalHomeクラスにDogCatの両方をマップすると、私は次の例外を取得します。 Dog 'を入力して ' MyNamespaceと入力します。 Cat '。

これは、キャッシュがそのタイプによってDogCatを区別しないと信じています。 Animal 1と考えて、Cat 1Dog 1と同じです。

どういうわけかキャッシュが実際のサブクラスを考慮に入れてもいいですか? また、これはtable-per-subclass構​​造では不可能な場合、このテーブルのマッピング方法はどうすればよいですか?

答えて

1

私はDiscriminatorをディッチすることでこれを解決しました。 WhereDogまたは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"); 
    } 
} 

キャッシュが今CatDogではないことを理解しています。