NHibernate / FluentNHibernate属性包 [英] NHibernate/FluentNHibernate property bag
问题描述
$ $ p $ code $ public class $ $
public virtual int Id {get;保护组}
公共虚拟字符串注册{get;组; }
私人列表< VehicleProperty> _properties = new List< VehicleProperty>();
public virtual IEnumerable< VehicleProperty>属性
{
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;组; }
公共虚拟字符串值{get;组;如何映射这两个类,以便VehicleProperty表有一个复合[VehicleId]和[Name]的键。车辆将是一个聚合根(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);
这个映射导致下面的sql和一个StaleStateException意外的行数:0;预计:1(我也不是真的想在VehicleProperty车辆财产)...
INSERT INTOVehicle(Registration)VALUES(@ p0);选择last_insert_rowid(); @ p0 ='AA09CDE'
UPDATEVehiclePropertySET Name = @ p0,Value = @ p1 WHERE Name = @ p2 AND Vehicle_Id = @ p3; @ p0 ='Color',@ p1 ='Black',@ p2 ='Color',@ p3 =''
反过来就是
另一个的反比关系。如果
没有其他的,那么只是不
更新。
您声明VehicleProperty.Name属性
作为主键。如果主
键已经初始化,NH
认为它已经存储了,
因此会尝试更新。 (这就是为什么你会得到这个异常。)你可以
改变了这种行为,但是使用一个人为的主要
键或映射波纹管是更好的
。
我不知道FluentNHibernate向您展示代码。我可以告诉你它在XML中的外观。
< class name =Vehicle>
< id name =Idgenerator =native/>
< property name =注册/>
<! - 声明属性Properties - >的Vehicle_Properties表。
< bag name =Propertiestable =Vehicle_Propertiescascade =all-delete-orphan>
<! - Vehicle_Properties和外键的主键 - >
< key column =Vehicle_FK/>
<! - 表格的内容:名称和值 - >
< composite-element class =VehicleProperty>
< property name =Name/>
< property name =Value/>
< / composite-element>
< / bag>
< / class>
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 = ''
解决方案
- Don't use composite id's.
- Inverse means, that this is the
inverse relation of an other one. If
there is no other one, it's just not
updated.
- You declared the VehicleProperty.Name Property
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.
<class name="Vehicle">
<id name="Id" generator="native"/>
<property name="Registration"/>
<!-- declare the table Vehicle_Properties for the property Properties -->
<bag name="Properties" table="Vehicle_Properties" cascade="all-delete-orphan">
<!-- primary key of Vehicle_Properties and foreign key -->
<key column="Vehicle_FK"/>
<!-- contents of the table: Name and Value -->
<composite-element class="VehicleProperty">
<property name="Name"/>
<property name="Value"/>
</composite-element>
</bag>
</class>
这篇关于NHibernate / FluentNHibernate属性包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!