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

时间:2014-09-18 22:55:16

标签: c# tfs tfs-workitem

我正在尝试在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发回一些关于每个项目中的内容的有用信息,但到目前为止看起来我只看到了工作项所包含的定义,而不是实际< / em> 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;
}

2 个答案:

答案 0 :(得分:11)

您需要使用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);
   }
}

答案 1 :(得分:0)

我确实需要使用 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");
            }