【问题标题】:Fluent NHibernate: map list of abstract class with table per concrete class (union-subclass)Fluent NHibernate:抽象类的映射列表,每个具体类都有表(联合子类)
【发布时间】:2012-11-24 19:04:55
【问题描述】:

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

我的班级结构如下:

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: 更新“车辆”SET Owner_id = @p0 WHERE Id = @p1] ---> System.Data.SQLite.SQLiteException: SQLite 错误

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

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

【问题讨论】:

    标签: nhibernate fluent-nhibernate


    【解决方案1】:

    在这种情况下,唯一的选择是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;
    

    【讨论】:

    • 谢谢,效果很好。它还可以通过将 Owner 对象添加到 Vehicle 对象,并在 VehicleMap 中使用 References() 来工作。然后 NHibernate 会自动在每个具体类表中创建 Owner_id 列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多