2010-05-06 6 views
15

J'essaie de tirer parti de NH pour mapper à un modèle de données qui est une interprétation approximative du modèle de données EAV/CR. J'ai la plupart de travail mais j'ai du mal à mapper la collection Entity.Attributes.Utilisation de NHibernate avec un modèle de données EAV

Voici les tableaux en question:

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

La colonne AttributeValue est mis en œuvre en tant que colonne sql_variant et je l'ai mis en œuvre un NHibernate.UserTypes.IUserType pour elle.

Je peux créer une entité EntityAttribute et la conserver directement afin qu'une partie de la hiérarchie fonctionne.

Je ne suis pas sûr comment mapper la collection EntityAttributes à l'entité Entity.

Notez le tableau EntityAttributes pourrait (et fait) contient plusieurs lignes pour une combinaison entityID donnée/de AttributeId:

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

StringAttributes ligne ressemble à ceci pour cet exemple:

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

Comment puis-je mapper efficacement ce modèle de données à mon domaine Entity de sorte que Entity.Attributes ("FavoriteColors") renvoie une collection de couleurs préférées? Tapé comme System.String?

+0

Vous utilisez couramment? –

+0

Si vous envisagez de trouver des entités par valeurs d'attribut, je ne suis pas sûr que sql_variant fonctionne correctement. Tu devrais essayer ça. –

Répondre

1

va ici

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