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

2 番目の動物を取得する前に最初の動物を立ち退かせると、うまくいきます。

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

Dogaと a の両方CatをクラスにマップするとAnimalHome、次の例外が発生します。

タイプ「MyNamespace」のオブジェクトをキャストできません。Dog ' と入力して 'MyNamespace. 」。

Dogこれにより、キャッシュはとCatをそのタイプで区別しないと思われます。と考えているだけで、それAnimal 1Cat 1等しいですDog 1

どうにかしてキャッシュに実際のサブクラスを考慮させることはできますか? または、サブクラスごとのテーブル構造でこれが不可能な場合、このテーブルのマッピングにどのようにアプローチすればよいですか?

4

1 に答える 1

1

Discriminatorを捨てることでこれを解決しました。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");
    }
}

キャッシュは、 a が aCatではないことを認識するようになりましたDog

于 2017-01-04T09:57:30.423 に答える