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 http://blogs.msdn.com/jmanning/archive/2005/09/21/472524.aspx


Comments (2)

  1. Buck Hodges says:

    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

  2. carlosstizza says:

    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