【问题标题】:Mapping self-referencing IDictionary<string, Entity> with Fluent NHibernate使用 Fluent NHibernate 映射自引用 IDictionary<string, Entity>
【发布时间】:2012-01-02 19:59:07
【问题描述】:

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

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 表的主键以及它从 Entity 继承的 Id。这就是我的映射工作方式:

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])) 必须具有与引用的主键(属性 [ParentAttributeId, Key])相同的列数

这是由于 NHibernate 在我的 Attribute 列中自动将 KeyId 一起设为主键。我希望 Key 不是主键,因为它出现在我所有的多对多表中;

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

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

【问题讨论】:

    标签: nhibernate dictionary fluent-nhibernate mapping


    【解决方案1】:
    • 您在哪里映射Attribute 本身(它是否包含复合键)?
    • AttributeValue 可能是一个更好的名称,以表明它包含一个值。
    • .AsMap(x =&gt; 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,
        )
    

    【讨论】:

      猜你喜欢
      • 2011-01-29
      • 2011-01-12
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多