简体   繁体   English

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

[英]How can I retrieve a list of workitems from TFS in C#?

I'm trying to write a project reporting tool in WPF / C#.我正在尝试用 WPF/C# 编写一个项目报告工具。 I want to access all the project names on our TFS (Team Foundation Server), and then display statistics for each work item in a given project.我想访问 TFS(Team Foundation Server)上的所有项目名称,然后显示给定项目中每个工作项的统计信息。

I've got the project names, but getting the actual work items is what's giving me a hard time.我已经知道了项目名称,但是获取实际的工作项让我很难受。 Here's what I've got so far:这是我到目前为止所得到的:

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 sends back some helpful info about what's in each project, but so far it looks like I'm only seeing the definitions of what the WorkItems consist of, and not the actual WorkItems themselves. GetProjectInfo 发送回有关每个项目中内容的一些有用信息,但到目前为止,我似乎只看到了 WorkItem 所包含内容的定义,而不是实际的WorkItem 本身。 I think the programming I've written is looking in the wrong place.我认为我写的程序找错了地方。

From Microsoft's definition of WorkItem, ( http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.workitemtracking.client.workitem.aspx ) it looks like it's inside WorkItemTracking.Client, but not inside the WorkItemStore, and I'm not sure where to go to access it.从 Microsoft 对 WorkItem 的定义来看,( http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.workitemtracking.client.workitem.aspx )它看起来像是在 WorkItemTracking.Client 内部,但不在 WorkItemStore 内部,我不知道去哪里访问它。

FINAL VERSION:最终版本:

Here's the updated version of my function, after referencing the below answer.这是我的函数的更新版本,参考以下答案。 This just returns a long string of the work item names with new lines between, for printing out, which is all I'm trying to get working (for now).这只是返回一长串工作项名称,中间有新行,用于打印,这就是我正在努力工作(目前)。

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;
}

You need to use WIQL queries to get actual work items you are interested in, eg to get all work items for a particular project:您需要使用 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);
   }
}

I do need to extract the linked Work Item (Testcases) as well with the Bug.我确实需要使用 Bug 提取链接的工作项(测试用例)。 I have created a query and it extracts both.我创建了一个查询,它提取了两者。 But my issue is while i print the Work Items Fields, All of the prints separately, with no trace of which Bug is linked to which Testcase.但我的问题是,当我打印工作项字段时,所有的打印件都是分开的,没有跟踪哪个 Bug 链接到哪个测试用例。 How can I achieve that.我怎样才能做到这一点。

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");
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM