2010-12-30 7 views
5

Dadas estas clases:Fluido NHibernate mapeo IDictionary <string, clase> de una manera inteligente

using System.Collections.Generic; 

namespace FluentMappingsQuestion 
{ 
    public class Entity 
    { 
     public virtual int Id { get; set; } 
     public virtual IDictionary<string, Property> Properties { get; set; } 
    } 

    public class Property 
    { 
     public virtual Entity OwningEntity { get; set; } 
     public virtual string Name { get; set; } 
     public virtual int Value { get; set; } 
     public virtual decimal OtherValue { get; set; } 
    } 
} 

¿Cómo puedo asignar usando NHibernate (sabor preferentemente con fluidez), de modo que al hacer esto es posible:

[Test] 
public void EntityPropertyMappingTest() 
{ 
    using (var session = _factory.OpenSession()) 
    { 
     var entity = new Entity(); 

     // (#1) I would *really* like to use this 
     entity.Properties["foo"] = new Property { Value = 42, OtherValue = 42.0M }; 

     session.Save(entity); 
     session.Flush(); 

     // (#2) I would like the entity below to "update itself" 
     // on .Save or .Flush. I got it to work with .Load() 
     Assert.AreEqual(42, entity.Properties["foo"].Value); 
     Assert.AreEqual(42.0M, entity.Properties["foo"].OtherValue); 
     Assert.AreEqual("foo", entity.Properties["foo"].Name); 
     Assert.AreEqual(entity, entity.Properties["foo"].Owner); 
    } 
} 

casi he logrado hacer esto con estas asignaciones:

// class EntityMap : ClassMap<Entity> 
public EntityMap() 
{ 
    Id(x => x.Id); 
    HasMany(x => x.Properties) 
    .Cascade.AllDeleteOrphan() 
    .KeyColumn("EntityId") 
    .AsMap(x => x.Name); 
} 

// class PropertyMap : ClassMap<Property> 
public PropertyMap() 
{ 
    Id(x => x.Id); 
    References(x => x.OwningEntity).Column("EntityId"); 
    Map(x => x.Name).Length(32); 
    Map(x => x.Value); 
{ 

Los problemas que tengo:

  • Si hago Entity.Properties.Inverse(), que comienza rompiendo
  • Si yo no lo hago entonces .Inverse() NHibernate hace: INSERT(Entity), INSERT(Property), UPDATE(Property) en lugar de sólo INSERT(Entity), INSERT(Property)
  • Si hago Property.Name.Not.Nullable(), se inicia rompiendo
  • Si no lo hago .Not.Nullable(), tengo un agujero en mi esquema db

¿Cómo debo cha nge mis mappings?

+0

Si realmente desea poder usar el código como: entity.Properties ["foo"] = 42; Entonces, ¿por qué ha creado esta clase de propiedad? ¿Por qué no hacer lo habitual de tener un IDictionary y luego asignarlo como un mapa de NHibernate? –

+0

@Paul: idealmente, me gustaría poder usar esto con clases, también con herencia. El ejemplo de código que pegué parece ser un poco confuso en esto. Lo actualizaré. –

Respuesta

4

trabajé en torno a este mediante la especificación de este mapeo:

HasMany<Property>(Reveal.Member<Entity>("InternalProperties")) 
    .AsMap(p => p.Name) 
    .Cascade.AllDeleteOrphan() 
    .Inverse(); 

y la creación de dos propiedades de tipo IDictionary<string, Property>: Properties y InternalProperties. El primero es un diccionario proxy sobre el segundo, y trata de establecer las propiedades OwningEntity y Name para las entradas Property.

Cuestiones relacionadas