Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for Handling NHibernate parent-child collections

So in a typical model where you have a parent that can have many children and a child that can have only one parent, how do you manage the adding of children. I have been using this approach;

public class Parent
{
    public Parent()
    {
        Children = new List<Child>();
    }

    public IList<Child> Children
    {
        get;
        private set;
    }
}

public class Child
{
    public Parent Parent
    {
        get;
        set;
    }
}

var child = new Child();
var parent = new Parent();
parent.Children.Add(child);
child.Parent = parent;

Problem is that everywhere i want to add a new child i've got to remember to add a reference to both the child and parent and its a bit of a pain. I could just add an AddChild method to the parent class and make that responsible for adding children - the problem now is that there is 2 ways to add a child, through the Children property and the method. So is this a better solution?

public class Parent
{
    public Parent()
    {
        children = new List<Child>();
    }

    private IList<Child> children
    {
        get;
        private set;
    }

    public IEnumerable<Child> Children
    {
        get
        {
            return children;
        }
    }

    public void AddChild(Child child)
    {
        children.Add(child);
        child.Parent = this;
    }
}

Are there any guidences for best practices on this, and what do you do?

like image 308
Gareth Avatar asked Jun 03 '09 10:06

Gareth


2 Answers

This is not an NHibernate problem at all.

You should implement the AddChild method. The classes are responsible for their consistency, so they shouldn't expose anything that should not be available. For instance, the (mutable) Children list should be hidden. Exposing an IEnumerable is a good idea.

Your second code is a good starting point. You probably need some more methods, like RemoveChild or CoundChildren.

like image 81
Stefan Steinegger Avatar answered Nov 16 '22 02:11

Stefan Steinegger


I do it like this:

public class Parent
{
    private ISet<Child> _children = new HashedSet<Child>();

    public ReadOnlyCollection<Child> Children
    {
        get{ return new List(_children).AsReadOnly(); }
    }

    public void AddChild( Child c )
    {
       if( c != null && !_children.Contains (d) )
       {
          c.Parent = this;
          _children.Add (c);
       }
    }
}

So, in fact, that's a bit what Stefan says as well. I just expose a readonly-copy of the Children list, so that you can easily iterate over the children of a parent, and get the number of children that the parent has. Adding and removing children to the parent, has to be done using the AddChild & RemoveChild member methods.

like image 24
Frederik Gheysels Avatar answered Nov 16 '22 01:11

Frederik Gheysels