Programmatically getting workitems associated with given changsets - inverese queries

I was looking for a quick sample on linking queries, but was surprised that I couldn't find one. There is "collectibles" sample in VSSDK that covers a lot on linking, but it is huge and I think a one pager sample would be helpful for most needs. So, I am posting a sample here. Here is sample on getting workitems associated with a given changeset.

        private List<WorkItem> GetWorkItemsForChangeSet(string serverName, int changeSet)

        {

            // Error handling code skipped for clarity.

            // Get TFS and store references.

            TeamFoundationServer server = TeamFoundationServerFactory.GetServer(serverName);

            WorkItemStore store = (WorkItemStore)server.GetService(typeof(WorkItemStore));

            ILinking linking = (ILinking)server.GetService(typeof(ILinking));

            // Get URI for changeset

            ArtifactId changeSetId = new ArtifactId();

            changeSetId.Tool = "VersionControl";

            changeSetId.ArtifactType = "ChangeSet";

            changeSetId.ToolSpecificId = changeSet.ToString();

            string changeSetUri = LinkingUtilities.EncodeUri(changeSetId);

  // Get referencing artifacts for given changeset

            Artifact[] artifacts = linking.GetReferencingArtifacts(new string[] { changeSetUri });

            List<WorkItem> workItems = new List<WorkItem>();

            foreach (Artifact artifact in artifacts)

            {

                ArtifactId artifactId = LinkingUtilities.DecodeUri(artifact.Uri);

                if (String.Equals(artifactId.Tool, "WorkItemTracking", StringComparison.OrdinalIgnoreCase))

                {

           WorkItem wi = store.GetWorkItem(Convert.ToInt32(artifactId.ToolSpecificId));

                    workItems.Add(wi);

                }

            }

            return workItems;

        }

Dll references needed:

Microsoft.TeamFoundation.Client.dll
Microsoft.TeamFoundation.Common.dll
Microsoft.TeamFoundation.WorkItemTracking.Client.dll

using Microsoft.TeamFoundation.Client;

using Microsoft.TeamFoundation;

using Microsoft.TeamFoundation.WorkItemTracking.Client;

 

The sample shows use of GetReferencingArtifacts. GetArtifacts can be used with similar syntax. Multiple URIs can be passed to "bulk" get artifacts.

Where to get documentation for ILinking and related methods?

There is a good documentation on linking in VSSDK under folder "Visual Studio 2005 SDK\<version>\VisualStudioTeamSystemIntegration\Team Foundation Core Services\Team Foundation Linking Service.doc". The "Collecibles" sample there shows how to extend linking to add new linktypes.

How to query on workitems associated with version control files?

The difficulty here is getting the ToolSpecificId for version control files (such as source code files). I am not aware of a way in UI. We could get it using version control object model or by adding a source control item in WI and checking the ArtifactUri propery in WorkItem's Links collection .

How to do the reverse, getting changesets for a workitem?

For getting changesets for multiple items in one shot, GetArtifacts method can be used. ToolSpecificId for workitems is workitem id. For a single item, using WIT object model is easy as described in the blog https://blogs.msdn.com/jmanning/archive/2005/09/21/472524.aspx

Comments

  • Anonymous
    August 08, 2006
    The version control Changeset object has an ArtifactUri property that returns the artifact uri for that changeset.  While you could manually build the artifact uri, as shown in the sample code, it's best to avoid it and treat the uri as being opaque.  Similarly, the Item object has an ArtifactUri property, which is what you'd want to use to get the artifact uri for a file or folder in version control (there are two types of artifact uri for an item: latest and a particular version).  To get an Item object, use the GetItem() or QueryItems() methods on the VersionControlServer object.

    Buck
  • Anonymous
    October 08, 2008
    I installed an example Collectibles in TFS 2005 and then in TFS 2008 with a success but has emerged a problem when trying to retrieve a WorkItem that is "Holds" an item Collectibles. The code is as follows:   Sub Main()      Dim servidor As String      servidor = "TFS2008"      Console.WriteLine()      Console.WriteLine("Obtiene los padres de la tarea 790")      ObtenerLosItemsPadresDelRequerimiento(servidor, 790)      Console.WriteLine()      Console.WriteLine("Presione ENTER para finalizar")      Console.ReadLine()   End Sub   Public Sub ObtenerLosItemsPadresDelRequerimiento(ByVal nombreServidorTFS As String, _                                                    ByVal idRequerimiento As Integer)      ObtenerLosItemsPadres(nombreServidorTFS, _                            "WorkItemTracking", _                            "WorkItem", _                            idRequerimiento)      Console.WriteLine()   End Sub   Public Sub ObtenerLosItemsPadres(ByVal nombreServidorTFS As String, _                                    ByVal herramienta As String, _                                    ByVal artefacto As String, _                                    ByVal id As Integer)      'Conecto al TFS      Dim tfs As TeamFoundationServer = ConectarTFS(nombreServidorTFS)      Dim almacen As WorkItemStore      Dim linkeo As ILinking      Dim idArtefacto As ArtifactId      Dim uriArtefacto As String      'Obtengo el almacen de WI      almacen = DirectCast(tfs.GetService(GetType(WorkItemStore)), WorkItemStore)      'Obtengo el servicio de linkeo      linkeo = DirectCast(tfs.GetService(GetType(ILinking)), ILinking)      'Obtengo el URI para el requerimiento      idArtefacto = New ArtifactId      idArtefacto.Tool = herramienta      idArtefacto.ArtifactType = artefacto      idArtefacto.ToolSpecificId = id.ToString      uriArtefacto = LinkingUtilities.EncodeUri(idArtefacto)      'Obtengo los requerimientos a los que referencia (outbound link)      Dim reqOut As Artifact()      Dim uriList(0) As String      uriList(0) = uriArtefacto      '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!      '    This the statement with error   !!!!!      '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!      reqOut = linkeo.GetReferencingArtifacts(uriList)      For Each it As Artifact In reqOut         Console.WriteLine(it.ArtifactTitle)      Next   End Sub When running the sentence "linkeo.GetReferencingArtifacts (uriList)" with remote debug, I note that the TFS invokes:   ''' <summary>   ''' Gets the Artifacts referring to the uris   ''' </summary>   ''' <param name="artifactUriList">the array of artifact URIs</param>   ''' <returns>the array of Collector Artifacts that refer to one or more URIs in uriList null if there are no such Collector Artifacts</returns>   <WebMethod()> _   Public Function GetReferencingArtifacts(ByVal artifactUriList() As String) As Microsoft.TeamFoundation.Artifact() Implements Microsoft.TeamFoundation.ILinkingConsumer.GetReferencingArtifacts But it turns out that artifactUriList () is Nothing! Gives the impression that the TFS is not carrying your product registered of the list of Uris as it was required in the original appeal, so the method GetReferencingArtifacts the Collector return nothing. The content of the tables is as follows: CollectorStore table ============= Id  Title                      ProjectUri 1    Coleccionista 1      vstfs:///Classification/TeamProject/2c879976-3089-45c6-a098-261c0f4f7628 2    Coleccionista 2      vstfs:///Classification/TeamProject/2c879976-3089-45c6-a098-261c0f4f7628 OutboundLinks table ============== CollectorId    Uri                                                                LinkType 1                   vstfs:///WorkItemTracking/Workitem/789     Points To 1                   vstfs:///WorkItemTracking/Workitem/790     Holds 2                   vstfs:///Collectibles/Collector/1                      Holds Any idea? Carlos Stizza carlos.stizza@ksoft.com.ar