2010-05-06 22 views
15

我想利用NH來映射到EAV/CR數據模型的鬆散解釋的數據模型。使用NHibernate的EAV數據模型

我大部分工作正常,但我正在努力與映射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集合映射到實體實體。

注意EntityAttributes表可以(不)包含給定ENTITYID /屬性Id組合多行:

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

StringAttributes行看起來像這樣在這個例子中:

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

我怎樣纔能有效地將此數據模型映射到我的實體域,以便Entity.Attributes(「FavoriteColors」)返回最喜歡的顏色集合?輸入爲System.String?

+0

是否使用流利? – 2012-04-16 09:07:43

+0

如果您打算通過屬性值查找實體,我不確定sql_variant是否正常工作。你應該試試這個。 – 2012-04-16 09:09:23

回答

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>(); 
      }); 
    } 
}