Friday, March 23, 2007

Getting Work Items from the Store

There’re few things I want to share about the WorkItemStore::GetWorkItem() method.
First, it may sound clear for everybody, but:

WorkItem a = wis.GetWorkItem(10);

WorkItem b = wis.GetWorkItem(10);

The instance a and b won’t be the same, you’ll have two separate objects for the same Work Item!

WorkItem instances could have been considered as singleton, with only one instance of a given WorkItem in the store. Would that made sense to you?
Personally, yes, it would.

GetWorkItem() is slooooow, I mean it, really, on my WebService which tracks states changes to synchronize related work item, I found out that 90% of the time execution was in that call (believe me, there’re much more than that in this WebService).As I was getting many time the same ID, I quickly made a class that implement a Work Item cache, based on a List<> (I know it’s maybe not the fastest way to find a occurrence from a given key, but well…)On my WebService, it turns out I was six times faster with this implementation…If Work Item were considered as singleton, I think I wouldn’t have had this performance issue.

And one last thing: if you modify a, then b, then a.Save() and b.Save(), you’ll have a nice exception throwing at you on the second Save call, with the impossibility to conciliate both changes (easily at least)…Not very cool !

Posted by Loïc Baumann in 16:39:41 | Permalink | Comments (1) »

Simple way to create Work Item Hierarchy

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)

    {

        // Hierarchy links have this comment

        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!

Posted by Loïc Baumann in 13:00:22 | Permalink | Comments (3)