2011-07-29 16 views
2

私はかなり単純な問題を抱えていますが、今はその点を見ることができません。 私の意図は、VehicleCollectorオブジェクトのリストを読み込むことです。それぞれのリストは、きれいな車リストと別の列車リストを持ちます。車両は単一のテーブルから来ており、TYPEという列で区別されます。FluentNHibernate SubClassMap Issue:Discriminator fail

モデルのコード:

public class VehicleCollector 
{ 
    public virtual IList<Car> Cars { get; set; } 
    public virtual IList<Train> Trains { get; set; } 
} 

public class Vehicle { } 

public class Car : Vehicle {} 

public class Train : Vehicle { } 

マッピングコード:

public class FooMap : ClassMap<VehicleCollector> 
{ 
    public FooMap() 
    { 
     this.HasMany(x => x.Cars).KeyColumn("foo_id"); 
     this.HasMany(x => x.Trains).KeyColumn("foo_id"); 
    } 
} 

public class VehicleMap : ClassMap<Vehicle> 
{ 
    public VehicleMap() { this.DiscriminateSubClassesOnColumn("type"); } 
} 

public class CarMap : SubclassMap<Car> 
{ 
    public CarMap() { this.DiscriminatorValue(1); } 
} 

public class TrainMap : SubclassMap<Train> 
{ 
    public TrainMap() { this.DiscriminatorValue(2); } 
} 

私はこの読みを維持するために意図的にIDおよびその他のプロパティを残しました。それはあなたがそれを実行した場合、コンパイルされません。

実際には、すべての車両がいずれかのコレクションにロードされているので、私の理解では、弁別者は無視されています。

ここで間違っていたり、間違っていることがありますか?

EDIT:私はSchemaExport to SQLiteを実行して、これがどのように動作するかを確認しました。ここでは何が起こっているかについて詳しく説明します。注:一部のプロパティが変更/追加されている可能性があります。

1)SchemaExportの

create table vehicle_collector 
(
    id INTEGER not null, 
    name TEXT not null, 
    primary key (id) 
); 

create table vehicle (
    id INTEGER not null, 
    desc TEXT not null, 
    type TEXT not null, 
    collector_id INTEGER, 
    primary key (id) 
); 

2)識別器をNHibernateは、静的文字列として配置されることに注意してください(これは、以下のSQLをもたらす

VehicleCollector c = new VehicleCollector() { Id = 1001, Name = "foobar" }; 
Train v2 = new Train() { Id = 101, desc = "Foo" }; 
Car v1 = new Car() { Id = 102, desc = "Bar" }; 
c.Cars.Add(v1); 
c.Trains.Add(v2); 
openSession.Save(c); 

を挿入):

これは、次のSQLになり

VehicleCollector v1 = openSession.CreateCriteria<VehicleCollector>() 
            .Add(Restrictions.Eq("Id", 1001L)) 
            .SetMaxResults(1) 
            .List<VehicleCollector>() 
            .First(); 
Assert.AreEqual(1, v1.Cars.Count); 
Assert.AreEqual(1, v1.Trains.Count); 

を選択

INSERT INTO vehicle_collector (name, id) VALUES (@p0, @p1); @p0 = 'foobar', @p1 = 1001; 
INSERT INTO vehicle (desc, type, id) VALUES (@p1, '2', @p2); @p1 = 'Foo', @p2 = 101; 
INSERT INTO vehicle (desc, type, id) VALUES (@p1, '1', @p2); @p1 = 'Bar', @p2 = 102; 
UPDATE vehicle SET collector_id = @p0 WHERE id = @p1; @p0 = 1001, @p1 = 101; 
UPDATE vehicle SET collector_id = @p0 WHERE id = @p1; @p0 = 1001, @p1 = 102; 

3)(なぜ何の弁別がここに存在しませんか?そして、何@ p1がために生成された最初のSELECT文である):意図したような作品を挿入しながら

SELECT this_.id as id0_0_, this_.name as name0_0_ 
    FROM vehicle_collector this_ 
    WHERE this_.id = @p0 limit 1; 
@p0 = 1001, @p1 = 1; 

SELECT vehicle0_.collector_id as collector5_1_, 
     vehicle0_.id  as id1_, 
     vehicle0_.id  as id1_0_, 
     vehicle0_.desc  as desc1_0_ 
    FROM vehicle vehicle0_ 
    WHERE vehicle0_.collector_id = @p0; 
@p0 = 1001; 

Obivously、NHibernateは2.1は、トラブルの識別器を使用して選択されています。新しいアイデアは?

TIA

+0

設定がテストされました(IDの追加) - 問題はありませんでした。私のテストコードはhttps://gist.github.com/1113933です。あなたの追加/クエリメソッドに問題があるかどうかを知りたい – codeprogression

+0

こんにちはリチャード、私は似たようなものを持っていますが、永続的なデータを読み込むために新しいセッションを使用すると、元の投稿に記述されているエラーが発生します。 –

+0

興味深いことに、Discriminatorを使ってInsertingがうまくいきます... –

答えて

2

私はそれが弁別情報のいずれかを含めていなかったので、選択する事が働いていなかった似たような(そうでない場合と同じ)を持っていました。これを追加し、常に含まれる弁別情報を強制するには:

this.DiscriminateSubClassesOnColumn("type").AlwaysSelectWithValue(); 

これは、クエリに含まれる識別情報を強制します。

+0

ありがとう、Docmanhattan、それはAlwaysSelectWithValueを使用して意図したとおりに動作します。 –