在TFS二次开发中,我们可能会根据某一些情况对各个项目的PBI、BUG等工作项进行统计。在本文中将大略讲解如果进行这些数据统计。
一:连接TFS服务器,并且得到之后需要使用到的类方法。
/// <summary> /// tfs的 /// </summary> private TfsTeamProjectCollection server; private WorkItemStore workstore; private TeamSettingsConfigurationService configSvc; private TfsTeamService teamService; public String TfsUri { get; set; } /// <summary> /// 初始化TFSServer /// </summary> /// <param name="model"></param> public TFSServerDto(string tfsUri) { this.TfsUri = tfsUri; Uri uri = new Uri(TfsUri); server = new TfsTeamProjectCollection(uri); workstore = (WorkItemStore)server.GetService(typeof(WorkItemStore)); configSvc = server.GetService<TeamSettingsConfigurationService>(); teamService = server.GetService<TfsTeamService>(); }
二:获取到本TFS Server 指定团队的所有项目
/// <summary> /// 获取项目集合 /// </summary> /// <returns></returns> public ProjectCollection GetProjectList() { return workstore.Projects; } public Project GetProject(int projectId) { return workstore.Projects.GetById(projectId); }
三:根据工作项类型获取工作项集合
/// <summary> /// 获取工作项统计 /// </summary> /// <param name="workitemtype">工作项类型:Bug,Impediment,Product Backlog Item,Task,Task Case</param> /// <returns></returns> public WorkItemCollection GetWorkItemCollection(string workitemtype, string projectName) { WorkItemCollection queryResults = GetWorkItemCollection(workitemtype,projectName, string.Empty); return queryResults; } /// <summary> /// 获取工作项统计 /// </summary> /// <param name="workitemtype">工作项类型:Bug,Impediment,Product Backlog Item,Task,Task Case等</param> /// <param name="condition">查询条件:针对Bug类型的 State=‘New,Approved,Committed,Done,Removed' /// 针对Impediment类型的State='Open' /// 针对Product Backlog Item类型的State='New' /// 针对Task类型的 State='To Do' /// 针对Task Case类型的 State='Design' /// <returns></returns> public WorkItemCollection GetWorkItemCollection(string workitemtype,string projectName,string condition) { string sql = @"Select [Title] From WorkItems Where [Work Item Type] = '{0}' and [System.TeamProject] = '{1}' "; if (!string.IsNullOrEmpty(condition)) { sql +=" and "+ condition; } sql = string.Format(sql, workitemtype, projectName); WorkItemCollection queryResults = workstore.Query(sql); return queryResults; }
四:获取Sprint信息和开始、结束时间
/// <summary> /// 获取项目的Sprint信息 /// </summary> /// <param name="projectUri">project的Uri信息</param> /// <returns></returns> public TeamSettings GetSprintInfo(String projectUri) { TeamFoundationTeam team = teamService.QueryTeams(projectUri).First(); IList<Guid> teamGuids = new List<Guid>() { team.Identity.TeamFoundationId }; TeamConfiguration config = configSvc.GetTeamConfigurations(teamGuids).FirstOrDefault(); var members = team.GetMembers(server, MembershipQuery.Direct); var users = members.Where(m => !m.IsContainer); return config.TeamSettings; } /// <summary> /// 获取项目Sprint的关键信息如开始时间和结束时间 /// </summary> /// <param name="projectUri"></param> /// <returns></returns> public IEnumerable<ScheduleInfo> GetIterationDates(string projectUri) { var css = server.GetService<ICommonStructureService4>(); NodeInfo[] structures = css.ListStructures(projectUri); NodeInfo iterations = structures.FirstOrDefault(n => n.StructureType.Equals("ProjectLifecycle")); List<ScheduleInfo> schedule = null; if (iterations != null) { string projectName = css.GetProject(projectUri).Name; XmlElement iterationsTree = css.GetNodesXml(new[] { iterations.Uri }, true); GetIterationDates(iterationsTree.ChildNodes[0], projectName, ref schedule); } return schedule; } /// <summary> /// 通过解析XML得到Sprint的开始和结束时间 /// </summary> /// <param name="node"></param> /// <param name="projectName"></param> /// <param name="schedule"></param> private void GetIterationDates(XmlNode node, string projectName, ref List<ScheduleInfo> schedule) { if (schedule == null) schedule = new List<ScheduleInfo>(); if (node != null) { string iterationPath = node.Attributes["Path"].Value; if (!string.IsNullOrEmpty(iterationPath)) { // Attempt to read the start and end dates if they exist. string strStartDate = (node.Attributes["StartDate"] != null) ? node.Attributes["StartDate"].Value : null; string strEndDate = (node.Attributes["FinishDate"] != null) ? node.Attributes["FinishDate"].Value : null; DateTime? startDate = null, endDate = null; if (!string.IsNullOrEmpty(strStartDate) && !string.IsNullOrEmpty(strEndDate)) { bool datesValid = true; // Both dates should be valid. startDate = DateTime.Parse(strStartDate); endDate = DateTime.Parse(strEndDate); schedule.Add(new ScheduleInfo { Path = iterationPath.Replace(string.Concat("\", projectName, "\Iteration"), projectName), StartDate = startDate, EndDate = endDate }); } } // Visit any child nodes (sub-iterations). if (node.FirstChild != null) { // The first child node is the <Children> tag, which we'll skip. for (int nChild = 0; nChild < node.ChildNodes[0].ChildNodes.Count; nChild++) GetIterationDates(node.ChildNodes[0].ChildNodes[nChild], projectName, ref schedule); } } }
五:获取团队成员名单
/// <summary> /// 获取项目的Sprint信息 /// </summary> /// <param name="projectUri">project的Uri信息</param> /// <returns></returns> public IEnumerable<TeamFoundationIdentity> GetMemberInfo(String projectUri) { TeamFoundationTeam team = teamService.QueryTeams(projectUri).First(); var members = team.GetMembers(server, MembershipQuery.Direct); var users = members.Where(m => !m.IsContainer); return users; }