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新しいプロパティでクラスを拡張します。

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追加されるときは、次のものも割り当てる必要があります。OwnerOwnerId

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