I am having some probs with my fluent mappings. I have an entity with a child collection of entities i.e Event and EventItems for example.
If I set my cascade mapping of the collection to AllDeleteOrphan I get the following error when saving a new entity to the DB: NHibernate.HibernateException : A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: Core.Event.EventItems
If I set the cascade to All it works fine? Below are my classes and mapping files:
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; }
}
Pretty stumped here. Any tips greatly appreciated.
Chev
You need to map _EventItems using an access strategy so that NHibernate access the private member instead of the property. You're getting this error because the collection reference is changed when the list is copied to a new List in _EventItems.ToList<EventItem>()
. Try this:
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();
}
}
}
I don't think the accepted answer is an elegant approach. The possible problem here is that Chev is reading Events from the database and then assigning a new EventItem
list to the EventItems
property. NHibernate throws this exception when you just ignore the previous children list and assign a new children list.
What you need to do here is,
If you want to discard the old EventItems
, do this instead:
events.EventItems.Clear();
events.EventItems.Add(new EventItem { blah blah });
Check this SO post: NHibernate: Delete a child record from the parent collection
The comments to the accepted answer has similar issue.
You may want to try removing AsReadOnly
for your EventItems
to check if that's the cause.
精彩评论