Given a Vehicle class and a VehicleProperty class…
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; }
}
How can I map the two classes so that the VehicleProperty table has a composite key of [VehicleId] and [Name]. Vehicle would be an aggregate root (VehicleProperty is not accessed outside of a Vehicle class).
I have tried everything that I can think of (I’m new to NHibernate so that’s not much)
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);
}
}
This mapping results in the below sql and a StaleStateException “Unexpected row count: 0; expected: 1” (I also don’t really want to have a Vehicle property on the VehicleProperty)…
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 = ''
inverse relation of an other one. If
there is no other one, it’s just not
updated.
as the primary key. if the primary
key is already initialized, NH
thinks it is already stored and
therefore tries an update. (that’s why you get the exception.) You can
changed this behaviour, but it’s
better to use an artificial primary
key or the mapping bellow.
I don’t know FluentNHibernate to show you the code. I can tell you how it looks in XML.