One child to multiple parents (kind of)

One child to multiple parents (kind of)

Old forum URL:

krasimir posted on Saturday, November 13, 2010

First, I already used the search function and read what I've found on this topic, but still I think my case is valid and want to ask for suggestions. Here is my scenario:

I develop a Bug tracking system and have such hierarchy:


  - Project

     - Bug

Now, the problem is that I want to introduce Comment object, which (obviously) will contains comment text, but I want to have comments for specific bug, as well as for specific project. Then my hierarchy will change to this:


  - Project

     - Comment

     - Bug

        - Comment

Since the by default do not support one child with multiple parents, what I currently have in mind, is to have two different classes - BugComment and ProjectComment, both of which will point to one table Comments in the database. The Comment table will not contain reference to its parent, since I don't know if the parent is Project or Bug, and there will be two additional tables ProjectComments and BugComments that will store the mappings between each comment and its parent.

However, this means that I have to introduce two different collection classes too - BugComments and ProjectComments.

Is there something that I'm missing here and is there an easier approach?


ajj3085 replied on Saturday, November 13, 2010

I think your plan seems fine, you're not violating any Csla rules with your plan.  There's no reason two Csla objects can't point to the same tables in the database.

You can get away with one Comments collection and Comment class; when calling UpdateChildren, call it like this:  UpdateChildren(this) or UpdateChildren(parentDataObj), then have two Child_[Insert | Update]s like this:  Child_Insert(Project proj) and Child_Insert(Bug bug) (and the corroposnding Updates). 

In this way you know exactly what the parent is and can insert the row in either BugComments or ProjectComments, as appropriate, and share the code which updates the Comments table.

Of course, this assumes Comments share behavior regardless of the type of parent.

krasimir replied on Monday, November 15, 2010

Thank you, Andy.

I like the idea with one class, but two Insert/Update methods - I'll try to see how it goes.

However, there is second part of my problem.

When I bild the UI later on (most probably Silverlight and ASP.NET MVC and/or WebForms), I would like to display a list with all comments form all projects/bugs from all users. This is not a problem. The problem is what if I select one particullar comment and want to delete it?

What I understand from the book (2008 edition) is that the only way to delete a child object is to go to its parent object and delete it from the its collection, that holds the child object. But how will I know which is the parent of my selected child form the UI list, when even the static GetXXX() method of the child class should be internal and not public?

I wonder, wouldn't be easier to make the all the static ChildClass.GetXXX() methods public, so when I select the comment in my list in the UI, I will be able to get the Parent of the comment, and if the parent of the comment is also a child class (the second case in my first posting on this topic), then I will be able to get the Project object throught its static GetProject() method and then, finally to get the root User object. Once I know which is the right root object, I can delete the comment object without a problem.

However, this seems not so ellegant to me, I probably I miss something. Moreover, I'm sure there is a good reason for Rocky to made the GetXXX() methods internal and not public.

Please advise.

ajj3085 replied on Thursday, November 18, 2010

So from your previous post, that object graph is for editing, and everything is saved within the root BO's context.  This list of all comments for all projects / bugs sounds like a different use case, so you'd have a different (likely readonly) set of business objects.  Immediate delete of a command can be accomplished by a DeleteComment command object.  

I wouldn't advise going the switchable object route, which sounds like what you're describing.  You'll be coupling two use cases together, and as soon as they have conflicting requirements, your code will be in trouble (and you'll need to split them at that point anyway).

Copyright (c) Marimer LLC