我遇到以下情况的问题。
我的班级结构如下:
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);
}
}
我插入一辆汽车和一辆自行车。当我尝试插入带有Vehicle对象列表的所有者(带有Car和Bicycle)时,我收到以下错误:
异常:NHibernate.Exceptions.GenericADOException:无法插入 采集: [NHibernateTest.Owner.Vehicles#8ace95bc-ad80-46d7-94c7-a11f012b67c6] [SQL: UPDATE“Vehicle”SET Owner_id = @ p0 WHERE Id = @ p1] ---&gt; System.Data.SQLite.SQLiteException:SQLite错误
由于我为每个具体类设置表,为什么NHibernate试图更新一个表示基类的不存在的表?这种情况不支持这种类型的映射吗?
此外,当我从HasMany更改为HasManyToMany时,这样可以正常工作。
答案 0 :(得分:2)
在这种情况下,唯一的选择是Inverse()
映射。这意味着混凝土车辆(汽车,自行车)必须关心关系的持久性。
要启用此功能,请使用新属性扩展Vehicle
类:
public abstract class Vehicle
{
..
// new owner independent navigation property
public virtual Guid OwnerId { get; set; }
}
并扩展Vehicle的映射
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;