我有一个非常简单的问题,但是现在似乎看不到重点。
我的意图是阅读一个VehicleCollector对象列表,每个对象都有一个整洁的Cars列表和另一个Trains列表。车辆来自单个表,并通过名为TYPE的列进行区分。
型号代码:
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;
显然,NHibernate 2.1在使用区分器进行选择时遇到了麻烦,同时按预期插入了作品。有什么新主意吗?
TIA
最佳答案
我有类似的东西(如果不一样的话),选择的东西不起作用,因为它不包含任何鉴别信息。要强制始终包含鉴别信息,请添加以下内容:
this.DiscriminateSubClassesOnColumn("type").AlwaysSelectWithValue();
这将强制将区分信息包含在查询中。