2010-05-06 16 views
15

Sto tentando di utilizzare NH per mappare un modello di dati che è un'interpretazione errata del modello di dati EAV/CR.Uso di NHibernate con un modello di dati EAV

Ho quasi tutto funzionante ma sto facendo fatica a mappare la raccolta Entity.Attributes.

Qui ci sono le tabelle in questione:

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

La colonna AttributeValue è implementato come una colonna sql_variant e ho implementato un NHibernate.UserTypes.IUserType per esso.

Posso creare un'entità EntityAttribute e persistere direttamente in modo che parte della gerarchia funzioni.

Non so come mappare la raccolta EntityAttributes all'entità Entity.

Nota tavolo EntityAttributes potrebbe (e lo fa) contenere più righe per una combinazione data EntityID/AttributeID:

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

StringAttributes fila si presenta così per questo esempio:

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

Come posso mappare in modo efficace questo modello di dati al mio dominio Entity in modo che Entity.Attributes ("FavoriteColors") restituisca una raccolta di colori preferiti? Digitato come System.String?

+0

Si sta utilizzando fluente? –

+0

Se si pianifica di trovare le entità in base ai valori degli attributi, non sono sicuro che sql_variant funzioni correttamente. Dovresti provare questo. –

risposta

1

qui va

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