如何在C#中从TFS检索工作项列表

本文关键字:检索 工作 列表 TFS 中从 | 更新日期: 2023-09-27 18:22:39

我正在尝试用WPF/C#编写一个项目报告工具。我想访问TFS(Team Foundation Server)上的所有项目名称,然后显示给定项目中每个工作项的统计信息。

我已经得到了项目名称,但得到实际的工作项目让我很难。到目前为止,我得到的是:

public const string tfsLocation = "http://whatever";
// get the top list of project names from the team foundation server
public List<string> LoadProjectList()
{
    var tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(tfsLocation));
    var workItemStore = new WorkItemStore(tpc);
    var projects = (from Project project in workItemStore.Projects select project.Name).ToList();
    return projects;
}
public string GetProjectInfo(string targetProject)
{
    string info = String.Empty;
    var tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(tfsLocation));
    var workItemStore = new WorkItemStore(tpc);
    foreach (Project project in workItemStore.Projects)
    {
        if (project.Name == targetProject)
        {
            info += String.Format("Project: {0}'n'n", project.Name);
            info += "Work Item Types:'n";
            foreach (WorkItemType item in project.WorkItemTypes)
            {
                info += String.Format("-   {0}'n", item.Name);
                info += String.Format("    -   Description: {0}'n", item.Description);
                info +=               "    -   Field Definitions:'n";
                foreach (FieldDefinition field in item.FieldDefinitions)
                {
                    info += String.Format("        -   {0}'n", field.Name);
                }
                info += "'n";
            }
        }
    }
    return info;
}

GetProjectInfo发回了一些关于每个项目中内容的有用信息,但到目前为止,我似乎只看到了WorkItems组成的定义,而没有看到实际的WorkItems本身。我觉得我写的程序找错地方了。

从微软对WorkItem的定义来看,(http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.workitemtracking.client.workitem.aspx)它看起来像是在WorkItemTracking.Client中,但不在WorkItemStore中,我不确定去哪里访问它。

最终版本:

这是我的函数的更新版本,参考了下面的答案。这只是返回一长串工作项名称,中间有新行,用于打印,这就是我(目前)所要做的全部工作。

public string GetProjectInfo(string targetProject)
{
    string info = String.Empty;
    var tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(tfsLocation));
    WorkItemStore workItemStore = new WorkItemStore(tpc);
    Query query = new Query(workItemStore, "SELECT * FROM WorkItems WHERE [System.TeamProject] = @project", new Dictionary<string, string>() { { "project", targetProject } });
    WorkItemCollection wic = query.RunQuery();
    foreach (WorkItem item in wic)
    {
        info += String.Format("{0}'n", item.Title);
    }
    return info;
}

如何在C#中从TFS检索工作项列表

您需要使用WIQL查询来获取您感兴趣的实际工作项,例如,获取特定项目的所有工作项:

using Microsoft.TeamFoundation.WorkItemTracking.Client;
Query query = new Query(
     workItemStore, 
     "select * from issue where System.TeamProject = @project",
     new Dictionary<string, string>() { { "project", project.Name } }
);
var workItemCollection = query.RunQuery();
foreach(Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem in workItemCollection) 
{
   /*Get work item properties you are interested in*/
   foreach(Microsoft.TeamFoundation.WorkItemTracking.Client.Field field in workItem.Fields)
   {
      /*Get field value*/
      info += String.Format("Field name: {0} Value: {1}'n", field.Name, field.Value);
   }
}

我确实需要提取链接的工作项(测试用例)以及Bug。我创建了一个查询,它提取了这两个查询。但我的问题是,当我打印工作项字段时,所有的打印都是单独的,没有任何痕迹表明哪个Bug与哪个测试用例有关。我怎样才能做到这一点。

public async Task<IList<WorkItem>> QueryOpenBugs(string project)
    {
        var credentials = new VssBasicCredential(string.Empty, this.personalAccessToken);
        // create a wiql object and build our query
        var wiql = new Wiql()
        {
            // NOTE: Even if other columns are specified, only the ID & URL are available in the WorkItemReference
            //Query = "Select [Id] " +
            //        "From WorkItems " +
            //        "Where [Work Item Type] = 'Bug' " +
            //        "And [System.TeamProject] = '" + project + "' " +
            //        "And [System.State] = 'Resolved' " +
            //        "Order By [State] Asc, [Changed Date] Desc",
            Query = "Select [System.Id],[System.WorkItemType],[System.Title]" +
                    "From workitemLinks " +
                    "Where ([Source].[System.WorkItemType] = 'Bug' " +
                    "And [Source].[System.TeamProject] = '" + project + "' " +
                    "And [Source].[System.State] = 'Resolved' )" +
                    "And ([Target].[System.TeamProject] = '" + project + "' " +
                    "And [Target].[System.WorkItemType] = 'Test Case' )",

        };
        using (var httpClient = new WorkItemTrackingHttpClient(this.uri, credentials))
        {
            // execute the query to get the list of work items in the results
            var result = await httpClient.QueryByWiqlAsync(wiql).ConfigureAwait(false);
            var ids = result.WorkItemRelations.Select(item => item.Target.Id).ToArray();
     
            // some error handling
            if (ids.Length == 0)
            {
                return Array.Empty<WorkItem>();
            }
            // build a list of the fields we want to see
            var fields = new[] { "System.Id", "System.Title", "System.State" , "System.IterationPath", "System.Tags", "Microsoft.VSTS.Common.StateChangeDate", "System.WorkItemType", "Microsoft.VSTS.TCM.AutomationStatus"};
            // get work items for the ids found in query
            return await httpClient.GetWorkItemsAsync(ids, fields, result.AsOf).ConfigureAwait(false);
        }
    }
    /// <summary>
    ///     Execute a WIQL (Work Item Query Language) query to print a list of open bugs.
    /// </summary>
    /// <param name="project">The name of your project within your organization.</param>
    /// <returns>An async task.</returns>
    public async Task PrintOpenBugsAsync(string project)
    {
        var workItems = await this.QueryOpenBugs(project).ConfigureAwait(false);
        Console.WriteLine("Query Results: {0} items found", workItems.Count);
        
        // loop though work items and write to console
        
        //Select - BugID , TestCaseID , TestSuiteID{} , ResolvedDate , AutomationStatus{}
        foreach (var workItem in workItems)
        {
            string WorkItemType = (string)workItem.Fields["System.WorkItemType"];
            if (WorkItemType == "Bug")
            {
                Console.WriteLine("The Bugs are:'n'n");
                Console.WriteLine(
                "{0}'t{1}'t{2}'t{3}'t{4}",
                workItem.Id,
                workItem.Fields["System.Title"],
                workItem.Fields["System.State"],
             //   workItem.Fields["System.RelatedLinks"],
                workItem.Fields["Microsoft.VSTS.Common.StateChangeDate"],
                workItem.Fields["System.WorkItemType"]);
                Console.WriteLine("'n");
            }
            else
            {
                Console.WriteLine("The TestCases are:'n'n");
                Console.WriteLine(
                "{0}'t{1}'t{2}'t{3}'t{4}",
                workItem.Id,
                workItem.Fields["System.Title"],
                workItem.Fields["System.State"],
                workItem.Fields["Microsoft.VSTS.TCM.AutomationStatus"],
                workItem.Fields["System.WorkItemType"]);
       
                Console.WriteLine("'n");
            }