使用Fluent NHibernate </string,>映射自引用IDictionary <string,entity =“”>

时间:2011-11-21 09:38:47

标签: nhibernate dictionary fluent-nhibernate mapping

我的域模型中有以下实体:

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列中自动将IdAttribute一起作为主键。我希望Key不是主键,因为它出现在我的所有多对多表中;

create table FooAttribute (
    FooId INT not null,
    AttributeId INT not null,
    [Key] NVARCHAR(255) not null
)

我希望外键仅引用Id而不是(Id, Key),因为将Key作为主键要求它是唯一的,它不会跨越我所有的ManyToMany

1 个答案:

答案 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,
    )