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 u
I do it like that except that I don't use property for private list
private IList<Child> _children
public IEnumerable<Child> Children
{
get
{
return children;
}
}
I'm using public IEnumerable with Add|Remove methods approach.
However I don't like it much, because it's not intuitive, and polutes class definition.
I'm wondering why people don't use CustomCollection where they override Add, Remove, Replace functions?? (like it's done everywhere in MS code) ????
I support the accepted solution to this question, however the solution presented is not complete, as using private fields requires some extra configuration in the mappers. For the benefit of others, the following is the complete solution:
public partial class Test
{
private readonly IList<Child> children = new List<Child>();
public virtual IEnumerable<Child> Children
{
get
{
return children;
}
}
}
Note that the publicly exposed collection must be virtual for NHibernate to use it. I also like to make it a readonly field that is initialised when the class is created to ensure it exists in all scenarios. Here is the associated mapper:
public class TestMap : ClassMap<Test>
{
...
HasMany(s => s.Children).Access.CamelCaseField();
}
The Access property tells NHibernate to use the private field when mapping values into the model. There are also other options on the Access property allowing various naming configurations to be used.
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.
If you have a foreign key in your DB, and you are using Identity(SQL Server) to generate your primary keys, you are going to NEED the backlink from the child to the parent. Else, the insert will complain on child because nhibernate needs to do some back and forth for the parent ID, but it hasn't done it yet.
What we ended up doing to get rid of backlinks : Use the NHibernate HiLo generator. This way, NHibernate always has the Ids it needs to insert your parent/child relations.
<3 !
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.