Create a custom field in all your concerned Work Items named "ParentWI" for instance, of type integer.
Now, say you want to link two Work Items, the method will looks like:
public void LinkWorkItems(WorkItem parent, WorkItem son)
{
RelatedLink rl = new RelatedLink(son.Id);
rl.Comment = "
parent.Links.Add(rl);
son.Fields["ParentWI"].Value = parent.Id;
son.Save();
parent.Save();
son.SyncToLatest();
}
I put a specific comment in the link to mark it as a hierarchy kind of link.
Take care to the last line, you may wonder why I do a SyncToLatest(), the reason is quite simple:
Work Item links are bi-directionals. Once you link a Work Item A to a Work Item B, the opposite link is created automatically when you save A.
Then you better do a SyncToLatest() to get the other Work Item up to date.
For our hierarchy evaluation, it might be a problem because you don’t know if the links you’ll evaluate are for children or the parent.
But there’s a simple way to evaluate if a given link is to a child: just get the ParentWI of that child and compare it with the current Work Item ID.
Here’s a snippet of a method that get all the children of a given Work Item:
public IEnumerable WIGetChildren(WorkItem wi)
{
ArrayList array = new ArrayList();
// We evaluate all the links for this Work Item
foreach (Link link in wi.Links)
{
//
if (link.Comment == "
{
// Get the linked Work Item
RelatedLink rl = link as RelatedLink;
if (rl == null)
{
// It’s another kind of link, go to the next one
continue;
}
// Get the corresponding Work Item
// (it’s supposed to be the child)
WorkItem linkedwi = GetWorkItem(rl.RelatedWorkItemId);
// Check if the ParentWI of the child is this Work Item
// If it’s not the case, it’s a child to parent relation
if (wi.Id != (int)linkedwi.Fields["ParentWI"].Value)
{
continue;
}
// It’s a child, we add it
array.Add(linkedwi);
}
}
return array;
}
That’s it, you have everything you need to implement hierarchy in your Work Items!