2010-12-30 8 views
5

Attribuite queste classi:Fluent NHibernate mappatura IDictionary <string, classe> in modo intelligente

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

Come posso mappare utilizzando NHibernate (sapore preferibilmente fluente), in modo che facendo questo è possibile:

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

ho quasi riuscito a farlo con questi mapping:

// 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); 
{ 

I problemi che ho:

  • Se faccio Entity.Properties.Inverse(), si comincia rompendo
  • Se non faccio che .Inverse() poi NHibernate fa: INSERT(Entity), INSERT(Property), UPDATE(Property) invece di INSERT(Entity), INSERT(Property)
  • Se faccio Property.Name.Not.Nullable(), comincia rompendo
  • Se non lo faccio .Not.Nullable(), ho un buco nel mio schema db

Come dovrei cha nge le mie mappature?

+0

Se si desidera utilizzare codice come: entity.Properties ["foo"] = 42; Allora perché hai creato questa classe di proprietà? Perché non fare la solita cosa di avere un IDictionary e quindi mapparlo come una mappa di NHibernate? –

+0

@Paul: Idealmente, mi piacerebbe poterlo usare anche con le classi, con l'ereditarietà. L'esempio di codice che ho incollato sembra essere un po 'oscuro su questo. Lo aggiornerò. –

risposta

4

ho lavorato intorno a questo specificando questa mappatura:

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

e la creazione di due proprietà di tipo IDictionary<string, Property>: Properties e InternalProperties. Il primo è un dizionario proxy sul secondo e si occupa dell'impostazione delle proprietà OwningEntity e Name per le voci Property.

Problemi correlati