2011-07-29 17 views
2

我有一個非常簡單的問題,但現在似乎無法看到這一點。 我的意圖是閱讀VehicleCollector對象列表,每個對象都有一個整齊的Cars列表和另一個列表列表。車輛來自單個表格,並且由名爲​​TYPE的列進行區分。FluentNHibernate SubClassMap問題:鑑別器失敗

型號代碼:

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和其它性能有意保持這種可讀。如果按照這種方式運行,它將不會編譯。實際上發生的事情是,所有的車輛都裝載到任何一個集合中,所以 - 根據我的理解 - 鑑別器被忽略了。

你有什麼想法我可能會在這裏錯過/做錯嗎?

編輯:我只是運行一個SchemaExport到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)插入

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(注意,鑑別器被放置爲通過NHibernate的靜態字符串):

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)選擇

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

這將導致下面的SQL(爲什麼沒有鑑別嗎?什麼是在生成的第一個SELECT語句@ P1):

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

有趣的是,插入工作正常使用鑑別器... –

回答

2

我有過類似的(如果不相同),其中,選擇的東西是行不通的,因爲它不包括任何的鑑別信息的東西。要強制鑑別信息總是被包括在內,補充一點:

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

這將迫使鑑別信息被列入查詢。

+0

謝謝,Docmanhattan,它按照預期使用AlwaysSelectWithValue。 –