How to retrieve linked “versioned item” from TFS

旧巷老猫 提交于 2020-01-04 15:17:08

问题


I have working code (thank you John Socha-Leialoha) that uses the TFS API to retrieve work items, along with all their linked work items (code below). However, what I'm trying to do is access the names of the linked Files (TFS calls it a "Versioned Item") for each work item. In the TFS GUI you can link a file to a work item. Say Work Item 1234 is linked to file foo.txt. Now when I run this query to find linked items, that file is not in the list - only other children WIs or parent WIs are returned. It's the same result if I create and run the query entirely in the GUI. How can I find out which files are linked to a given WI? The only way I can now is to look at the WI in the TFS GUI, and it shows in the Files list in the lower right.

Perhaps I just need to do a normal flat query, fetch the WI fields, and somehow the names of the linked files would be one of the fields of that WI? I don't need to download the linked file, I just need the filename/location.

Code to return all linked WIs is here:

public List<string> GetLinkedItems()
{
    //executes a linked item query, returning work items, as well as the items that are link to them.
    //gets digital asset work item that contains the given part number in the Assoc. Parts field
    var result = new List<string>();
    var tpc = new TfsTeamProjectCollection(new Uri(_tfsUri));
    var workItemStore = (WorkItemStore) tpc.GetService(typeof (WorkItemStore));
    //and [Schilling.TFS.TechPub.AssocParts] CONTAINS '101-4108' 
    var query =
        "SELECT [System.Id], [System.Links.LinkType], [System.TeamProject]," +
        " [System.WorkItemType], [System.Title], [System.AssignedTo]," +
        " [System.State] FROM WorkItemLinks " +
        " WHERE ([Source].[System.TeamProject] = 'Tech Pubs'  AND " +
        " [Source].[System.WorkItemType] = 'DigitalAsset'  AND " +
        " [Source].[System.State] <> '') And " +
        " ([System.Links.LinkType] <> '') And " +
        " ([Target].[System.WorkItemType] <> '') " +
        " ORDER BY [System.Id] mode(MayContain)";
    var treeQuery = new Query(workItemStore, query);
    //Note we need to call RunLinkQuery here, not RunQuery, because we are doing a link item type of query
    var links = treeQuery.RunLinkQuery();

    //// Build the list of work items for which we want to retrieve more information//
    int[] ids = (from WorkItemLinkInfo info in links
                 select info.TargetId).Distinct().ToArray();

    //
    // Next we want to create a new query that will retrieve all the column values from the original query, for
    // each of the work item IDs returned by the original query.
    //
    var detailsWiql = new StringBuilder();
    detailsWiql.AppendLine("SELECT");
    bool first = true;

    foreach (FieldDefinition field in treeQuery.DisplayFieldList)
    {
        detailsWiql.Append("    ");
        if (!first)
            detailsWiql.Append(",");
        detailsWiql.AppendLine("[" + field.ReferenceName + "]");
        first = false;
    }
    detailsWiql.AppendLine("FROM WorkItems");
    //
    // Get the work item details
    //
    var flatQuery = new Query(workItemStore, detailsWiql.ToString(), ids);
    WorkItemCollection details = flatQuery.RunQuery();

    return
        (from WorkItem wi in details
         select wi.Id + ", " + wi.Project.Name + ", " + wi.Title + ", " + wi.State).ToList();
}

回答1:


Work item queries can only show WorkItemLinkType links. To get links of other types (i.e. files in source control), you need to go through the list of links in the WorkItem object itself. Here's a snippet of code that will get you the artifact of the file linked to the work item:

TfsTeamProjectCollection tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
    new Uri("http://<server>:8080/tfs/<collection>"));

WorkItemStore wiStore = tpc.GetService<WorkItemStore>();

VersionControlServer vc = tpc.GetService<VersionControlServer>();

WorkItem task = wiStore.GetWorkItem(<work item with a linked file>);

var externalLinks = task.Links.OfType<ExternalLink>();

foreach (var link in externalLinks)
{
    XmlDocument artifact = vc.ArtifactProvider.GetArtifactDocument(new Uri(link.LinkedArtifactUri));
}

The XML document contains all necessary information needed to grab the correct file version from the VersionControlServer using the GetItem() method.



来源:https://stackoverflow.com/questions/14993147/how-to-retrieve-linked-versioned-item-from-tfs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!