Programmatically finding a Stored Query Definition within TFS2010

Today I’m building a small utility and have a requirement to execute a stored work item query from within Team Foundation Server 2010. Previously I’d used the StoredQueries collection on the Project instance to find a query by name … however it would appear that this was depreciated as part of the TFS2010 release.

I was surprised to find that there doesn’t seem to be a simple replacement for finding a specified stored query by name – part of me thinks I must be missing a simpler solution, however if anyone else is encountering the same issue I hope that the following code snippet will be of use.

Required namespaces:

  • Microsoft.TeamFoundation.Client
  • Microsoft.TeamFoundation.WorkItemTracking.Client

/// <summary>
/// <para>Find the TFS QueryDefinition for a specified Team Project</para>
/// <para>Note that if multiple queries match the requested queryName
/// only the first will be used</para>
/// </summary>
/// <param name=”tfsUrl”>URL to the TFS project, including the
/// collection name (Eg, http://tfsserver:8080/tfs/DefaultCollection)</param>

/// <param name=”projectName”>Name of TFS Team Project</param>
/// <param name=”queryName”>Name of Stored Query. Note if multiple
/// exist the first found will be used</param>

/// <returns></returns>
public static QueryDefinition FindQueryItem(string tfsUrl, string projectName, string queryName)
{

// Setup the connection to TFS
TfsTeamProjectCollectionprojectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(tfsUrl));

WorkItemStore workItemStore = projectCollection.GetService<WorkItemStore>();

Project project = workItemStore.Projects[projectName];

return FindQueryItem(queryName, project.QueryHierarchy);

}

///<summary>
/// Recursively find the QueryDefinition based on the requested queryName.
///<para>Note that if multiple queries match the requested queryName
/// only the first will be used</para>
///</summary>
///<param name=”queryName”>Name of Stored Query. Note if multiple exist
/// the first found will be used</param>

///<param name=”currentNode”>Pointer to the current node in the recursive search</param>
///<returns>QueryDefinition</returns>
private static QueryDefinition FindQueryItem(string queryName, QueryItem currentNode)

{

// Attempt to cast to a QueryDefinition
QueryDefinitionqueryDefinition = currentNode as QueryDefinition;

// Check if we’ve found a match
if
(queryDefinition != null && queryDefinition.Name == queryName)

return queryDefinition;

// Attempt to cast the current node to a QueryFolder
QueryFolder
queryFolder = currentNode as QueryFolder;

// All further checks are for child nodes so if this is not an
// instance of QueryFolder then no further processing is required.

if
(queryFolder == null)

return null;

// Loop through all the child query item
foreach (QueryItem qi in queryFolder)
{

// Recursively call FindQueryItem
QueryDefinition
ret = FindQueryItem(queryName, qi);

// If a match is found no further checks are required
if
(ret != null)

return ret;

}

return null;

}

Advertisements