NHibernate/FluentNHibernate属性包

Oll*_*Oll 4 nhibernate fluent-nhibernate

给定一个Vehicle类和一个VehicleProperty类......

public class Vehicle
{
    public virtual int Id { get; protected set; }
    public virtual string Registration { get; set; }

    private List<VehicleProperty> _properties = new List<VehicleProperty>();
    public virtual IEnumerable<VehicleProperty> Properties
    {
        get { return _properties; }
        protected set{ _properties = new List<VehicleProperty>(value);}
    }

    public virtual void AddProperty(string name, string value)
    {
        _properties.Add(new VehicleProperty {Name = name, Value = value});
    }
}

public class VehicleProperty
{
    public virtual string Name { get; set; }
    public virtual string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如何映射这两个类,以便VehicleProperty表具有[VehicleId]和[Name]的复合键.Vehicle将是聚合根(VehicleProperty不在Vehicle类之外访问).

我已经尝试了所有我能想到的东西(我是NHibernate的新手,所以并不多)

public class VehicleMap : ClassMap<Vehicle>
{
    public VehicleMap()
    {
        Id(x => x.Id);
        Map(x => x.Registration);
        HasMany(x => x.Properties)
            .Inverse()
            .Cascade.All();
    }
}

public class VehiclePropertyMap : ClassMap<VehicleProperty>
{
    public VehiclePropertyMap()
    {
        UseCompositeId()
            .WithKeyProperty(x => x.Name)
            .WithKeyReference(x => x.Vehicle, "Vehicle_Id");
        Map(x => x.Name);
        Map(x => x.Value);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个映射导致下面的sql和StaleStateException"意外的行数:0;期望:1"(我也不想在VehicleProperty上有一个Vehicle属性)...

INSERT INTO "Vehicle" (Registration) VALUES (@p0); select last_insert_rowid(); @p0 = 'AA09CDE'
UPDATE "VehicleProperty" SET Name = @p0, Value = @p1 WHERE Name = @p2 AND Vehicle_Id = @p3; @p0 = 'Colour', @p1 = 'Black', @p2 = 'Colour', @p3 = ''
Run Code Online (Sandbox Code Playgroud)

Jam*_*ory 6

我完全赞同Stefan的观点,虽然我无法证明他的映射的正确性,但是对Fluent NHibernate的字面翻译如下:

public class VehicleMap : ClassMap<Vehicle>
{
  public VehicleMap()
  {
    Id(x => x.Id);
    Map(x => x.Registration);

    HasMany(x => x.Properties)
      .Component(c =>
      {
        c.Map(x => x.Name);
        c.Map(x => x.Value);
      })
      .Cascade.AllDeleteOrphan();
  }
}
Run Code Online (Sandbox Code Playgroud)