简体   繁体   中英

Update NHibernate object with child collection

I am trying to update an nHibernate object with a child collection using the .Update() method found on a hibernate session. The only thing that I can do with the current setup is add children, I can not modify them or remove them.

For clarification the objects and their mapping are as follows:

public class Parent {
   public virtual int Id { get; set; }
   public virtual string Name { get; set; }
   public virtual ISet<Child> Children { get; set; } = new HashSet<Child>();
}

public class ParentMap: ClassMap<Parent>
{
   public ParentMap()
   {
     Id(x => x.Id);
     Map(x => x.Name);
     HasMany(x => x.Children)
       .AsSet()
       .Inverse()
       .Cascade.AllDeleteOrphan();
   }
}

public class Child {
   public virtual int Id { get; set; }
   public virtual string Name { get; set; }
   public virtual Parent Parent { get; set; }
}

public class ChildMap: ClassMap<Child>
{
   public ChildMap()
   {
       Id(x => x.Id);
       Map(x => x.Name);
       References(x => x.Parent);        
   }
}

When I get changes from my UI layer and try to update the already existing object using:

using (var tx = _session.BeginTransaction())
     _session.Update(newParent);
     tx.Commit();
}

Here newParent is a transient object (obtained from the database in an earlier session andd shown in the UI) containing the same identifier as the object I would like to update, but with changes to the child collection. Somehow using this approach I can only add children, but not modify or remove them.

Where is my mistake?

Most likely what is happening to you, is that instead of modifying the set that NHibernate has instantiated in your Parent entity, you are replacing it all together by a new instance of HashSet .

When you save or get an entity from NHibernate, your Children ISet gets loaded with an instance of a PersistentGenericSet (that implements ISet ) which has the responsibility of helping with this change tracking for your collection.

In short, do not assign to the Children property. In fact, make the setter protected . Just Add() or Remove() or Clear() it as required.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM