我的域模型中有以下实体:
class Entity
{
public int Id { get; set; }
}
class Foo : Entity
{
public IDictionary<string, Attribute> Attributes { get; set; }
}
class Bar : Entity
{
public IDictionary<string, Attribute> Attributes { get; set; }
}
class Attribute : Entity
{
public string Key { get; set; }
public string Value { get; set; }
public IDictionary<string, Attribute> Attributes { get; set; }
}
我想用Fluent NHibernate映射这些词典。我已经完成了大部分工作,但首先我遇到了自引用Attribute.Attributes
属性的问题。这是由于NHibernate使Key
成为Attribute
表的主键以及它从Id
继承的Entity
。这就是我的映射的工作原理:
ManyToManyPart<Attribute> manyToMany = mapping
.HasManyToMany<Attribute>(x => x.Attributes)
.ChildKeyColumn("AttributeId")
.ParentKeyColumn(String.Concat(entityName, "Id"))
.AsMap(x => x.Key, a => a.Column("`Key`"))
.Cascade.AllDeleteOrphan();
if (entityType == typeof(Attribute))
{
manyToMany
.Table("AttributeAttribute")
.ParentKeyColumn("ParentAttributeId");
}
如果我用以下内容替换if
语句:
if (entityType == typeof(Attribute))
{
manyToMany
.Table("Attribute")
.ParentKeyColumn("ParentAttributeId");
}
我得到以下异常:
NHibernate.FKUnmatchingColumnsException:外键(FK_Attribute_Attribute [ParentAttributeId]))必须与引用的主键具有相同的列数(Attribute [ParentAttributeId,Key])
这是因为NHibernate会在Key
列中自动将Id
与Attribute
一起作为主键。我希望Key
不是主键,因为它出现在我的所有多对多表中;
create table FooAttribute (
FooId INT not null,
AttributeId INT not null,
[Key] NVARCHAR(255) not null
)
我希望外键仅引用Id
而不是(Id, Key)
,因为将Key
作为主键要求它是唯一的,它不会跨越我所有的ManyToMany
。
答案 0 :(得分:1)
Attribute
本身(它是否包含复合键)?AttributeValue
可能是一个更好的名称,表明它包含一个值。 .AsMap(x => x.Key)
足以说Key应该是字典键
create table FooAttribute (
FooId INT not null,
AttributeValueId INT not null
)
或考虑使用
mapping.HasMany(x => x.Attributes)
.KeyColumn(entity + Id)
.AsMap(x => x.Key)
.Cascade.AllDeleteOrphan();
将创建
create table Attribute (
Id INT not null,
FooId INT,
BarId INT,
ParentAttributeId INT,
Key TEXT,
Value TEXT,
)