2010-05-06 4 views
15

저는 NH를 활용하여 EAV/CR 데이터 모델에 대한 느슨한 해석 인 데이터 모델에 매핑하려고합니다.EAV 데이터 모델로 NHibernate 사용하기

나는 그것의 대부분을 가지고 있지만 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 조합에 대한 여러 행을 포함 :

StringAttributes 행이 예를 들면 다음과 같습니다

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

:

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

어떻게 할 수 Entity.Attributes ("FavoriteColors")가 좋아하는 색상 모음을 반환하도록이 데이터 모델을 내 Entity 도메인에 효과적으로 매핑합니까? System.String으로 입력 되었습니까?

+0

간다? –

+0

속성 값으로 엔티티를 찾으려면 sql_variant가 제대로 작동하는지 잘 모르겠습니다. 이것을 시도해야합니다. –

답변

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