C# TFS获取具有关系和子项的项
我需要一些有关Microsoft TFS的帮助。(或VSTS,如果我错了,请纠正我) 我想得到,对于一个给定的项目,所有的关系和孩子。 我能够得到关系,但我不了解子项(例如,给定待办事项下的所有任务,以及所有相关任务/bug等)。最后,我想展示一个树(或者一个包含所有关系的graphQL样式的显示) 这是我课堂的一部分:C# TFS获取具有关系和子项的项,c#,tfs,visual-studio-2017,C#,Tfs,Visual Studio 2017,我需要一些有关Microsoft TFS的帮助。(或VSTS,如果我错了,请纠正我) 我想得到,对于一个给定的项目,所有的关系和孩子。 我能够得到关系,但我不了解子项(例如,给定待办事项下的所有任务,以及所有相关任务/bug等)。最后,我想展示一个树(或者一个包含所有关系的graphQL样式的显示) 这是我课堂的一部分: using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models; using Microsoft.TeamFound
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.TeamFoundation.Client;
using Microsoft.VisualStudio.Services.Client;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
public TfsDataProvider(string tfsInstanceUrl, string tfsCollection)
{
TfsInstanceUrl = tfsInstanceUrl.TrimEnd('/');
TfsCollection = tfsCollection;
TfsUrlPlusCollection = string.Format("{0}/{1}", tfsInstanceUrl, tfsCollection);
//tfs nuget packages for API version 3.2:
creds = new VssCredentials();
creds.Storage = new VssClientCredentialStorage();
Uri url = new Uri(TfsUrlPlusCollection); //"http://tfs:8080/tfs/aeronautics-100"
connection = new VssConnection(url, creds);
wiClient = connection.GetClient<WorkItemTrackingHttpClient>();
//tracker = new HashSet<int>();
}
public List<WorkItem> GetWorkItemsByIds(IEnumerable<int> ids)
{
var wis = wiClient.GetWorkItemsAsync(ids, null, null, WorkItemExpand.Relations).Result;
return wis;
}
使用Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
使用Microsoft.TeamFoundation.Client;
使用Microsoft.VisualStudio.Services.Client;
使用Microsoft.VisualStudio.Services.Common;
使用Microsoft.VisualStudio.Services.WebApi;
公共TfsDataProvider(字符串tfsInstanceUrl、字符串tfsCollection)
{
TfsInstanceUrl=TfsInstanceUrl.TrimEnd('/');
TfsCollection=TfsCollection;
tfsurlpluscolection=string.Format(“{0}/{1}”,tfsInstanceUrl,tfscolection);
//API 3.2版的tfs nuget软件包:
creds=新的VssCredentials();
creds.Storage=新的VssClientCredentialStorage();
Uri url=新Uri(TfsUrlPlusCollection);/“http://tfs:8080/tfs/aeronautics-100"
连接=新的VssConnection(url、creds);
wiClient=connection.GetClient();
//tracker=newhashset();
}
公共列表GetWorkItemsById(IEnumerable ID)
{
var wis=wiClient.GetWorkItemsAsync(id,null,null,WorkItemExpand.Relations);
返回wis;
}
上面的代码起作用了,我收到了所有的项目和它们的关系,然后我可以通过id获得这些关系,并构建一个树来显示。
我的问题是,我不明白我怎样才能把所有的孩子都带回来
目前,我想向这个函数发送一个id数组(此时为1个id),并递归地获取它的所有子项和关系。看来我只得到了关系
我使用的是2017版TFS,API版本是3.2 所有链接的工作项都包含在关系中,因此您的代码已经获得了子工作项。下一步是检查关系类型,以确定哪个是相关工作项,哪个是子工作项
foreach (WorkItem wi in wis)
{
if (wi.Relations != null)
{
foreach (WorkItemRelation wir in wi.Relations)
{
Console.WriteLine(wir.Rel);
Console.WriteLine(wir.Url);
}
}
}
链接类型:
Child: System.LinkTypes.Hierarchy-Forward
Parent: System.LinkTypes.Hierarchy-Reverse
Related: System.LinkTypes.Related
只需递归地获取所有子工作项 例如:
private static void GetWorkItemsTest()
{
//var creds = new VssCredentials();
// creds.Storage = new VssClientCredentialStorage();
VssCredentials c = new VssCredentials(new Microsoft.VisualStudio.Services.Common.VssBasicCredential(string.Empty, "{PAT}"));
Uri url = new Uri("https://starain.visualstudio.com");
var connection = new VssConnection(url, c);
var wiClient = connection.GetClient<WorkItemTrackingHttpClient>();
IEnumerable<int> ids = new List<int> { 851, 180 };
var wis = wiClient.GetWorkItemsAsync(ids, null, null, WorkItemExpand.Relations).Result;
foreach (WorkItem wi in wis)
{
Console.WriteLine(wi.Id);
GetChildrenWIT(wiClient, wi, 1,new List<int> { wi.Id.Value});
}
}
private static void GetChildrenWIT(WorkItemTrackingHttpClient witClient, WorkItem child, int width,List<int> existingWit)
{
if (child.Relations != null)
{
foreach (WorkItemRelation wir in child.Relations)
{
var indent = new string('-', width);
int id = int.Parse(wir.Url.Split('/').Last());
if(!existingWit.Contains(id))
{
Console.WriteLine(string.Format("{0}{1}", indent, wir.Rel));
var childwit = witClient.GetWorkItemAsync(id, null, null, WorkItemExpand.Relations).Result;
existingWit.Add(childwit.Id.Value);
Console.WriteLine(string.Format("{0}-{1}", indent, childwit.Id));
GetChildrenWIT(witClient, childwit, width+1, existingWit);
}
}
}
}
private static void GetWorkItemsTest()
{
//var creds=新的VssCredentials();
//creds.Storage=新的VssClientCredentialStorage();
VssCredentials c=新的VssCredentials(新的Microsoft.VisualStudio.Services.Common.vssbasiccredentials(string.Empty,“{PAT}”);
Uri url=新的Uri(“https://starain.visualstudio.com");
var连接=新的VssConnection(url,c);
var wiClient=connection.GetClient();
IEnumerable id=新列表{851180};
var wis=wiClient.GetWorkItemsAsync(id,null,null,WorkItemExpand.Relations);
foreach(wis中的工作项目wi)
{
控制台写入线(wi.Id);
GetChildrenWIT(wiClient,wi,1,新列表{wi.Id.Value});
}
}
私有静态void GetChildrenWIT(WorkItemTrackingHttpClient witClient、WorkItem child、整型宽度、列表现有Wit)
{
if(child.Relations!=null)
{
foreach(子关系中的工作项关系)
{
var indent=新字符串('-',宽度);
int id=int.Parse(wir.Url.Split('/').Last());
如果(!existingWit.Contains(id))
{
WriteLine(string.Format(“{0}{1}”,indent,wir.Rel));
var childwit=witClient.GetWorkItemAsync(id,null,null,WorkItemExpand.Relations);
existingWit.Add(childwit.Id.Value);
WriteLine(string.Format(“{0}-{1}”,缩进,childwit.Id));
GetChildrenWIT(witClient,childwit,宽度+1,现有Wit);
}
}
}
}
结果如下:
我刚刚遇到了一个类似的问题,要获得有关关系的信息,您必须使用GetWorkItemAsync方法的WorkItemExpand参数:
var item = client.GetWorkItemAsync(c_projectName, id, null, null, WorkItemExpand.Relations).Result;
如果不使用此参数,关系属性将为空。谢谢Eddie Chen!这是我遗漏的部分,链接类型。谢谢你的回答!我已经开始使用类似于您的示例的方法,但我得到了堆栈溢出异常,可能是因为循环依赖,每个子级都有一个到父级的链接,我尝试递归地获取它。不管怎样,Eddie Chen关于链接类型的提示帮助我找到了答案。再次感谢你。