【问题标题】:Using NHibernate with an EAV data model将 NHibernate 与 EAV 数据模型一起使用
【发布时间】:2011-07-29 20:54:32
【问题描述】:

我正在尝试利用 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 域,以便 Entity.Attributes("FavoriteColors") 返回最喜欢的颜色集合?键入为 System.String?

【问题讨论】:

  • 如果您打算按属性值查找实体,我不确定 sql_variant 是否正常工作。你应该试试这个。

标签: nhibernate nhibernate-mapping entity-attribute-value


【解决方案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>();
            });
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多