3

我在以下情况下遇到问题。

我的班级结构如下:

public class Owner
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Vehicle> Vehicles { get; set; }
}

public abstract class Vehicle
{
    public virtual long Id { get; set; }
    public virtual string Name { get; set; }
}

public abstract class PoweredVehicle : Vehicle
{
    public virtual string EngineType { get; set; }
}

public class Car : PoweredVehicle
{
    public virtual int Doors { get; set; }
}

public class Truck : PoweredVehicle
{
    public virtual long MaxLoad { get; set; }
}

public class Bicycle : Vehicle
{
    public virtual int FrameSize { get; set; }
}

流畅的映射:

public class OwnerMap : ClassMap<Owner>
{
    public OwnerMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Name);
        HasMany(x => x.Vehicles);
    }
}

public class VehicleMap : ClassMap<Vehicle>
{
    public VehicleMap()
    {
        Id(x => x.Id).GeneratedBy.HiLo("10");
        Map(x => x.Name);
        UseUnionSubclassForInheritanceMapping();
    }
}

public class PoweredVehicleMap : SubclassMap<PoweredVehicle>
{
    public PoweredVehicleMap()
    {
        Map(x => x.EngineType);
        Abstract();
    }
}

public class CarMap : SubclassMap<Car>
{
    public CarMap()
    {
        Map(x => x.Doors);
    }
}

public class TruckMap : SubclassMap<Truck>
{
    public TruckMap()
    {
        Map(x => x.MaxLoad);
    }
}

public class BicycleMap : SubclassMap<Bicycle>
{
    public BicycleMap()
    {
        Map(x => x.FrameSize);
    }
}

我插入汽车和自行车。当我尝试插入带有车辆对象列表的所有者(带有汽车和自行车)时,我收到以下错误:

异常:NHibernate.Exceptions.GenericADOException:无法插入集合:[NHibernateTest.Owner.Vehicles#8ace95bc-ad80-46d7-94c7-a11f012b67c6][SQL: UPDATE "Vehicle" SET Owner_id = @p0 WHERE Id = @p1] -- -> System.Data.SQLite.SQLiteException:SQLite 错误

由于我为每个具体类设置表,为什么 NHibernate 试图更新一个不存在的表,它代表基类?此方案不支持这种类型的映射吗?

此外,当我从 HasMany 更改为 HasManyToMany 时,这工作正常。

4

1 回答 1

2

在这种情况下,唯一的选择是Inverse()映射。这意味着具体的 Vehicle (Car, Bicycle) 必须关心关系的持久性。

Vehicle要启用此功能,请使用新属性扩展类:

public abstract class Vehicle
{ 
  ..
  // new owner independent navigation property
  public virtual Guid OwnerId { get; set; } 
}

并扩展车辆的映射

public VehicleMap()
{  
  ..
  Map(x => x.OwnerId).Column("Owner_id);
}

最后颠倒持久性责任。不是所有者,但集合项将关心正确的Owner_id列更改(当Vehicle调用具体的插入/更新时)。

(更多关于逆:https ://stackoverflow.com/a/1454445/1679310 )

public OwnerMap()
{
  ..
  HasMany(x => x.Vehicles)
    .Inverse()
    .Cascade.All();
}

Vehicle被添加到Owner的集合中时,它OwnerId也必须被赋值:

owner.Vehicles.Add(car);
car.OwnerId = owner.Id;
于 2012-12-06T18:58:49.413 回答