2010-01-24 3 views
15

Ich habe einige Probs mit meinen fließenden Mappings. Ich verfüge über eine Entität mit einer Kindsammlung von Entitäten, z. B. Event und EventItems.nhibernate mapping: Eine Sammlung mit cascade = "all-delete-orphan" wurde nicht mehr referenziert

Wenn ich meine Kaskade Zuordnung der Sammlung AllDeleteOrphan ich die folgende Fehlermeldung erhalten, wenn eine neue Einheit an die DB zu speichern: NHibernate.HibernateException: Eine Sammlung mit Kaskade = „all-löschen-Waise“ wurde nicht mehr referenziert durch die besitzende Entity-Instanz: Core.Event.EventItems

Wenn ich die Kaskade auf All einstellen, funktioniert es gut? Unten sind meine Klassen und Mapping-Dateien:

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

Ziemlich ratlos hier. Irgendwelche Tipps sehr geschätzt.

Chev

+0

Warum Sie subclassmap verwenden Sie? Ist das ein Tippfehler? – Paco

Antwort

19

Sie müssen _EventItems mithilfe einer Zugriffsstrategie zuordnen, damit NHibernate auf das private Mitglied statt auf die Eigenschaft zugreift. Sie erhalten diesen Fehler, weil der Sammlungsverweis geändert wird, wenn die Liste in _EventItems.ToList<EventItem>() in eine neue Liste kopiert wird. Versuchen Sie dies:

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 - Ich kann dir sagen, wie dankbar ich bin! Hier verrückt werden. – Chev

0

prüft diesen SO Beitrag: NHibernate: Delete a child record from the parent collection

Die Kommentare zu der akzeptierten Antwort hat ähnliches Problem.

Sie können versuchen, AsReadOnly für Ihre EventItems zu entfernen, um zu überprüfen, ob das die Ursache ist.

+0

Danke für die Antwort - hat das Problem nicht gelöst. Siehe die Antwort von Jamie. Das hat es gelöst. Danke für die Antwort. – Chev

17

Ich glaube nicht, dass die akzeptierte Antwort eine elegante Vorgehensweise ist. Das mögliche Problem hier ist, dass Chev Ereignisse aus der Datenbank liest und dann eine neue EventItem Liste der EventItems Eigenschaft zuweist. NHibernate löst diese Ausnahme aus, wenn Sie die vorherige untergeordnete Liste ignorieren und eine neue untergeordnete Liste zuweisen.

Was müssen Sie hier zu tun ist,

Wenn Sie die alte EventItems verwerfen wollen, tun Sie stattdessen:

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

Dies ist der beste Ansatz, um dies zu lösen. Vielen Dank! – elvin

Verwandte Themen