2010-01-24 10 views
15

Tengo algunos problemas con mis asignaciones fluidas. Tengo una entidad con una colección secundaria de entidades, por ejemplo Event y EventItems.mapeo nhibernate: una colección con cascade = "all-delete-huérfano" ya no se hace referencia

si configuro el mapeo cascada de la colección a AllDeleteOrphan me sale el error al guardar una nueva entidad con el PP: NHibernate.HibernateException: Una colección con cascada = "all-delete-orphan" ya no se hace referencia por instancia de la entidad propietaria: Core.Event.EventItems

Si configuro la cascada en Todo, ¿funciona bien? Debajo están mis clases y archivos de mapeo:

public class EventMap : ClassMap<Event> 
{ 
    public EventMap() 
    { 
     Id(x => x.Id, "Id") 
      .UnsavedValue("00000000-0000-0000-0000-000000000000") 
      .GeneratedBy.GuidComb(); 

     Map(x => x.Name); 
     HasMany(x => x.EventItems) 
      .Inverse() 
      .KeyColumn("EventId") 
      .AsBag() 
      .Cascade.AllDeleteOrphan(); 
    } 
} 

    public class EventItemMap : SubclassMap<EventItem> 
{ 
    public EventItemMap() 
    { 
     Id(x => x.Id, "Id") 
      .UnsavedValue("00000000-0000-0000-0000-000000000000") 
      .GeneratedBy.GuidComb(); 
     References(x => x.Event, "EventId"); 
    } 
} 



public class Event : EntityBase 
{ 
    private IList<EventItem> _EventItems; 

    protected Event() 
    { 
     InitMembers(); 
    } 

    public Event(string name) 
     : this() 
    { 
     Name = name; 
    } 

    private void InitMembers() 
    { 
     _EventItems = new List<EventItem>(); 
    } 

    public virtual EventItem CreateEventItem(string name) 
    { 
     EventItem eventItem = new EventItem(this, name); 
     _EventItems.Add(eventItem); 
     return eventItem; 
    } 

    public virtual string Name { get; private set; } 
    public virtual IList<EventItem> EventItems 
    { 
     get 
     { 
      return _EventItems.ToList<EventItem>().AsReadOnly(); 
     } 
     protected set 
     { 
      _EventItems = value; 
     } 
    } 
} 

    public class EventItem : EntityBase 
{ 
    protected EventItem() 
    { 
    } 

    public EventItem(Event @event, string name):base(name) 
    { 
     Event = @event; 
    } 

    public virtual Event Event { get; private set; } 
} 

Bastante perplejo aquí. Cualquier consejo muy apreciado.

Chev

+0

¿Por qué usan subclassmap? ¿Es eso un error tipográfico? – Paco

Respuesta

19

Debe asignar _EventItems utilizando una estrategia de acceso para que NHibernate acceda al miembro privado en lugar de a la propiedad. Obtiene este error porque la referencia de la colección se cambia cuando la lista se copia en una nueva lista en _EventItems.ToList<EventItem>(). Pruebe esto:

public class EventMap : ClassMap<Event> 
{ 
    public EventMap() 
    { 
     Id(x => x.Id, "Id") 
      .UnsavedValue("00000000-0000-0000-0000-000000000000") 
      .GeneratedBy.GuidComb(); 

     Map(x => x.Name); 
     HasMany(x => x.EventItems) 
      .Access.PascalCaseField(Prefix.Underscore) 
      .Inverse() 
      .KeyColumn("EventId") 
      .AsBag() 
      .Cascade.AllDeleteOrphan(); 
     } 
    } 
} 
+0

Jamie - ¡Te puedo decir lo agradecido que estoy! Estar loco aquí. – Chev

0

Comprobar la presente OS mensaje: NHibernate: Delete a child record from the parent collection

Las observaciones a la respuesta aceptada tiene problema similar.

Es posible que desee intentar eliminar AsReadOnly para su EventItems para comprobar si esa es la causa.

+0

Gracias por la respuesta: no resolvió el problema. Ver la respuesta de Jamie. Eso lo resolvió Gracias por la respuesta sin embargo. – Chev

17

No creo que la respuesta aceptada sea un enfoque elegante. El posible problema aquí es que Chev está leyendo Eventos de la base de datos y luego asigna una nueva lista EventItem a la propiedad EventItems. NHibernate arroja esta excepción cuando ignora la lista de niños anterior y asigna una nueva lista de niños.

Lo que hay que hacer aquí es,

Si desea descartar el viejo EventItems, debe hacerse lo siguiente:

events.EventItems.Clear(); 
events.EventItems.Add(new EventItem { blah blah }); 
+0

Este es el mejor enfoque para resolver esto. ¡Gracias! – elvin

Cuestiones relacionadas