mapeo nhibernate: una colección con cascade="all-delete-huérfano" ya no estaba referenciada
fluent-nhibernate nhibernate-mapping (3)
Estoy teniendo algunos problemas con mis asignaciones fluidas. Tengo una entidad con una colección secundaria de entidades, por ejemplo, Event y EventItems.
Si configuro mi mapeo en cascada de la colección a AllDeleteOrphan, obtengo el siguiente error al guardar una nueva entidad en la base de datos: NHibernate.HibernateException: una instancia con entidad en cascada = "all-delete-orphan" ya no estaba referenciada por la instancia de la entidad propietaria : Core.Event.EventItems
Si configuro la cascada a Todo, ¿funciona bien? A continuación 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
Debe asignar _EventItems usando una estrategia de acceso para que NHibernate acceda al miembro privado en lugar de a la propiedad. Recibirá este error porque la referencia de la colección se modifica cuando la lista se copia a una Lista nueva en _EventItems.ToList<EventItem>()
. Prueba 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();
}
}
}
Marque esta publicación SO: NHibernate: eliminar un registro secundario de la colección principal
Los comentarios a la respuesta aceptada tienen un problema similar.
Es posible que desee intentar eliminar AsReadOnly
para que sus EventItems
verifiquen si esa es la causa.
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 de artículos de EventItem
a la propiedad EventItems
. NHibernate lanza esta excepción cuando simplemente ignora la lista de hijos anterior y asigna una nueva lista de hijos.
Lo que necesitas hacer aquí es,
Si desea descartar los EventItems
antiguos, haga esto en su lugar:
events.EventItems.Clear();
events.EventItems.Add(new EventItem { blah blah });