2010-12-30 7 views
5

Biorąc pod uwagę te zajęcia:Fluent NHibernate mapowania IDictionary <string, klasa> w inteligentny sposób

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

Jak mogę mapować je za pomocą NHibernate (najlepiej płynny aromat), tak, że ten sposób jest możliwe:

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

mam prawie udało się zrobić z tych odwzorowań:

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

problemy mam:

  • Jeśli zrobię Entity.Properties.Inverse(), rozpoczyna łamanie
  • Jeśli nie uda .Inverse() następnie NHibernate robi: INSERT(Entity), INSERT(Property), UPDATE(Property) zamiast tylko INSERT(Entity), INSERT(Property)
  • Jeśli zrobię Property.Name.Not.Nullable(), rozpoczyna łamanie
  • Jeśli nie zrobię tego .Not.Nullable(), mam dziurę w moim schemacie db

Jak powinienem nge moje mapowania?

+0

Jeśli naprawdę chcesz mieć możliwość używania kodu takiego jak: entity.Properties ["foo"] = 42; Dlaczego więc utworzyłeś tę klasę Property? Dlaczego po prostu nie robić zwykłej rzeczy o IDictionary , a następnie mapować go jako mapę NHibernate? –

+0

@Paul: Idealnie, chciałbym móc używać tego z klasami, także z dziedziczeniem. Przykład kodu, który wkleiłem, wydaje się niejasny. Zaktualizuję to. –

Odpowiedz

4

pracował obejść przez określenie to odwzorowanie:

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

i tworząc dwa miejsca typu IDictionary<string, Property>: Properties i InternalProperties. Pierwszy to słownik proxy nad drugim i dotyczy ustawiania właściwości OwningEntity i Name dla wpisów Property.

Powiązane problemy