15

NH を活用して、EAV/CR データ モデルの大まかな解釈であるデータ モデルにマップしようとしています。

私はそれのほとんどを機能させていますが、Entity.Attributes コレクションのマッピングに苦労しています。

問題のテーブルは次のとおりです。

--------------------
| Entities         |
--------------------
| EntityId  PK     |-|
| EntityType       | |
-------------------- |
         -------------
         |
         V
--------------------
| EntityAttributes |    ------------------    ---------------------------
--------------------    | Attributes     |    | StringAttributes        |
| EntityId  PK,FK  |    ------------------    ---------------------------
| AttributeId  FK  | -> | AttributeId PK | -> | StringAttributeId PK,FK |
| AttributeValue   |    | AttributeType  |    | AttributeName           |
--------------------    ------------------    ---------------------------

AttributeValue 列は sql_variant 列として実装されており、そのために NHibernate.UserTypes.IUserType を実装しました。

EntityAttribute エンティティを作成し、それを直接永続化して、階層の一部が機能するようにすることができます。

EntityAttributes コレクションを Entity エンティティにマップする方法がわかりません。

EntityAttributes テーブルには、特定の EntityId/AttributeId の組み合わせに対して複数の行が含まれる可能性がある (実際に含まれている) ことに注意してください。

EntityId AttributeId AttributeValue
-------- ----------- --------------
1        1           Blue
1        1           Green

この例では、StringAttributes 行は次のようになります。

StringAttributeId AttributeName
----------------- --------------
1                 FavoriteColor

Entity.Attributes("FavoriteColors") がお気に入りの色のコレクションを返すように、このデータ モデルをエンティティ ドメインに効果的にマップするにはどうすればよいですか? System.String として入力されましたか?

4

1 に答える 1

1

ここに行きます

class Entity
{
    public virtual int Id { get; set; }

    internal protected virtual ICollection<EntityAttribute> AttributesInternal { get; set; }

    public IEnumerable<T> Attributes<T>(string attributeName)
    {
        return AttributesInternal
            .Where(x => x.Attribute.Name == attributeName)
            .Select(x => x.Value)
            .Cast<T>();
    }
}

class EntityAttribute
{
    public virtual Attribute Attribute { get; set; }

    public virtual object Value { get; set; }
}

class EntityMap : ClassMap<Entity>
{
    public EntityMap()
    {
        HasMany(e => e.AttributesInternal)
            .Table("EntityAttributes")
            .KeyColumn("EntityId")
            // EntityAttribute cant be an Entity because there is no real Primary Key
            // (EntityId, [AttributeId] is not unique)
            .Component(c =>
            {
                c.References(ea => ea.Attribute, "AttributeId").Not.LazyLoad();
                c.Map(ea => ea.Value, "AttributeValue").CustomType<VariantUserType>();
            });
    }
}
于 2011-07-29T12:54:32.893 に答える