问题:鉴别器失败

本文关键字:失败 鉴别 问题 | 更新日期: 2023-09-27 18:03:49

我有一个相当简单的问题,但现在似乎不明白这一点。我的目的是读取一个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和其他属性。如果你按原来的方式运行它,它将无法编译。

实际发生的情况是,所有车辆都被加载到其中一个集合中,因此-在我的理解中-鉴别器被忽略了。

你知道我在这里可能遗漏了什么/做错了什么吗?

EDIT:我刚刚运行了一个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(为什么这里没有discriminator ?第一个生成的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

问题:鉴别器失败

我也遇到过类似的情况(如果不是相同的话),因为没有包含任何鉴别符信息,所以选择东西不工作。要强制包含鉴别符信息ALWAYS,请添加:

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

这将强制在查询中包含标识符信息