TFS API get work item data

Jhon Enamo Casas picture Jhon Enamo Casas · Jan 13, 2015 · Viewed 13.9k times · Source

i m stuck on simple problem with TFS API, when im getting work item, i cant get workitem Effort data, the idea is to get work item form the TFS by specific criteria, and then change Effort data and save it back to the TFS. Now i can get work item, and update any data by field, but i din;t found how to get Effort, and update it.

enter image description here

Query for getting data from TFS:

SELECT * FROM WorkItems WHERE [System.WorkItemType] = 'Task' AND [Assigned to] = 'name' 
ORDER BY [System.WorkItemType], [System.Id]

And this is the code to fetch the fields

public void getDataFromTfs()
{
    Console.WriteLine("Getting data from TFS to Store");
    Console.WriteLine("*********************");
    setQuery();
    Console.WriteLine("Query" + byTasksModified.ToString());
    Console.WriteLine("*********************");
    Console.ReadLine();
    credentials = new System.Net.NetworkCredential("xxxxx", "xxxxxx", "xxxxx");
    TfsTeamProjectCollection teamProjectCollection =
    new TfsTeamProjectCollection(new Uri(@"LINK HERE"), credentials);
    teamProjectCollection.EnsureAuthenticated();
    Store = (WorkItemStore) teamProjectCollection.GetService(typeof(WorkItemStore));
    WIC = Store.Query(byTasksAssignedTo);
    Console.WriteLine("Data fetched into Store");
    foreach (WorkItem workItem in WIC)
    {
        Console.WriteLine("ID: {0}", workItem.Id);
        Console.WriteLine("Title: {0}", workItem.Title);
    }
}

Here I'm getting all tasks that i need by specific query, and then i have method to pull specific task

public void getSpecificWorkItemData()
{
    workItem = Store.GetWorkItem(64);
    Console.WriteLine("ID: {0}", workItem.Id);
    Console.WriteLine("Title: {0}", workItem.Title);

    workItem.Open();
    Console.ReadLine();
}

and then i have update method for the task

public void updateWorkItem()
{
   workItem.Fields["Assigned to"].Value = "NAME";

   if (workItem.IsValid() == false)
   {
       Console.WriteLine("Item is not valid");
   }
   else
   {
        try
        {
            workItem.Save();
        }
        catch (ValidationException exception)
        {
            Console.WriteLine("Error saving work item!");
            Console.WriteLine(exception.Message);
        }
        Console.WriteLine("Item Saved");
        workItem.Close();
        Console.ReadLine();
    }
}

Answer

jessehouwing picture jessehouwing · Jan 13, 2015

It depends on your process template which fields are available. Right now you're querying on "Task" work items, which has the following fields in the "Effort" group by default. Note that there is no "Effort" field for tasks, there are these other:

Process Template    | Field (s)
Scrum               | Remaining Work
MSF Agile           | Remaining Work, Completed Work, Original estimate
MSF CMMI            | Remaining Work, Completed Work, Original estimate

The Effort field you're after is defined in the Scrum process template and is used by all work items in the Requirement Category (Product Backlog Item and Bug by default):

Process Template    | Field (s)
Scrum               | Effort
MSF Agile           | Story Point
MSF CMMI            | Size

If you want to update the Effort field in the work items in the Scrum Process template, it's best to query work items that are in the Work Item Type Category "Requirement Category":

SELECT * 
    FROM WorkItems 
    WHERE [System.TeamProject] = @project  
        AND  [System.WorkItemType] IN GROUP 'Requirement Category'  
    ORDER BY [System.Id]

If you want to update the Remaining work, Completed Work or Original Estimate fields, you need to use the Tasks:

SELECT id, Microsoft.VSTS.Scheduling.CompletedWork, Microsoft.VSTS.Scheduling.RemainingWork, Microsoft.VSTS.Scheduling.OriginalEstimate
    FROM WorkItems 
    WHERE [System.TeamProject] = @project  
        AND  [System.WorkItemType] IN GROUP 'Task Category'  
    ORDER BY [System.Id]

And then update them based on their Ref name, as defined in the TFS Field Reference, is the safest way to go:

workItem.Fields["Microsoft.VSTS.Scheduling.CompletedWork"].Value = 123;
workItem.Fields["Microsoft.VSTS.Scheduling.RemainingWork"].Value = 123;
workItem.Fields["Microsoft.VSTS.Scheduling.OriginalEstimate"].Value = 123;