Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在API中获得完整的TFS迭代细节_C#_Tfs_Iteration_Workitem - Fatal编程技术网

C# 如何在API中获得完整的TFS迭代细节

C# 如何在API中获得完整的TFS迭代细节,c#,tfs,iteration,workitem,C#,Tfs,Iteration,Workitem,我正在尝试扫描TFS,查找sprint中曾经出现过的工作项。 现在,通过正常的TFS查询,您可以搜索迭代Id,并使用Was Ever操作符,但要获得该Id,您必须拥有一个已知的工作项,该项在某个时间点(当前或其历史记录中)存在 我已经能够在路径是否是积压工作或sprint迭代的地方进行组装,这些迭代的开始和停止日期,但ID不是 理想情况下,我希望提供其Guid或其路径以获取其ID, 但是没有,我在哪里可以得到 目前,我获得的迭代树包含以下内容: public static IterationTr

我正在尝试扫描TFS,查找sprint中曾经出现过的
工作项。
现在,通过正常的TFS查询,您可以搜索
迭代Id
,并使用
Was Ever
操作符,但要获得该Id,您必须拥有一个已知的
工作项
,该项在某个时间点(当前或其历史记录中)存在

我已经能够在路径是否是积压工作或sprint迭代的地方进行组装,这些迭代的开始和停止日期,但ID不是

理想情况下,我希望提供其
Guid
或其路径以获取其ID, 但是没有,我在哪里可以得到

目前,我获得的迭代树包含以下内容:

public static IterationTreeItem GetIterationTree()
{
    var structures = TfsShared.Instance.CommonStructureService.ListStructures(TfsShared.Instance.ProjectInfo.Uri);
    var iterationNode = structures.First(_ => _.Name == "Iteration");

    var rawIterationTree = TfsShared.Instance.CommonStructureService.GetNodesXml(new[] { iterationNode.Uri }, true);
    var iterationTree = rawIterationTree.FirstChild;

    var teams = TfsShared.Instance.AllTeams.ToList();

    var configs = TfsShared.Instance.TeamSettingsConfigurationService
                     .GetTeamConfigurations(teams.Select(_ => _.Identity)
                                                 .Select(_ => _.TeamFoundationId));

    var backLogPaths = configs.Select(_ => _.TeamSettings.BacklogIterationPath)
                                  .OrderBy(_ => _)
                                  .Distinct()
                                  .ToArray();

    var fullTree = new IterationTreeItem(iterationTree);

    var iterationList = IterationTreeItem.Flatten(fullTree).ToList();

    IterationTreeItem.SetBackLogsOrSprints(iterationList, backLogPaths);
    return fullTree;
}
[DebuggerDisplay("{CleanIterationPath,nq}")]
public class IterationTreeItem
{
    private readonly List<IterationTreeItem> _children = new List<IterationTreeItem>();

    public IterationTreeItem(XmlNode node)
    {
        if (node != null)
        {
            XmlNode = node;

            var nodeId = GetNodeId(node);

            NodeInfo = TfsShared.Instance.CommonStructureService.GetNode(nodeId);
            if (node.FirstChild != null)
            {
                var children = node.FirstChild.ChildNodes.OfType<XmlNode>()
                                   .Select(_ => new IterationTreeItem(_, this))
                                   .ToArray();

                Children.AddRange(children);
            }
        }
    }

    private IterationTreeItem(XmlNode node, IterationTreeItem parent)
        : this(node)
    {
        Parent = parent;
    }

    public List<IterationTreeItem> Children
    {
        get { return _children; }
    }

    public string CleanBacklogPath
    {
        get
        {
            var parts = CleanIterationPath.Split('\\').ToArray();
            return string.Join("\\", parts.Take(Math.Max(parts.Length - 1, 1)));
        }
    }

    public string CleanIterationPath
    {
        get
        {
            if (NodeInfo != null)
            {
                var notStartedWithSlashes = NodeInfo.Path.Substring(1);
                return notStartedWithSlashes.Replace("\\Iteration", string.Empty);
            }
            return string.Empty;
        }
    }
    public bool? IsProductBackLogIteration { get; private set; }

    public bool? IsSprintIteration { get; private set; }

    public NodeInfo NodeInfo { get; private set; }

    public IterationTreeItem Parent { get; private set; }

    public XmlNode XmlNode { get; private set; }

    public static IEnumerable<IterationTreeItem> Flatten(IterationTreeItem item)
    {
        yield return item;
        foreach (var childChild in item.Children.SelectMany(Flatten))
        {
            yield return childChild;
        }
    }

    public static void SetBackLogsOrSprints(IEnumerable<IterationTreeItem> items, IEnumerable<string> knownBacklogs)
    {
        var backLogs = knownBacklogs as List<string> ?? knownBacklogs.ToList();
        foreach (var iterationTreeItem in items)
        {
            if (backLogs.Any(_ => _ == iterationTreeItem.CleanIterationPath))
            {
                iterationTreeItem.IsProductBackLogIteration = true;
                iterationTreeItem.IsSprintIteration = false;
            }
            else
            {
                iterationTreeItem.IsProductBackLogIteration = false;
                iterationTreeItem.IsSprintIteration = true;
            }
        }
    }

    private static string GetNodeId(XmlNode node)
    {
        if (node.Attributes != null)
        {
            var otherNodeId = node.Attributes.OfType<XmlAttribute>().First(_ => _.Name == "NodeID").Value;
            return otherNodeId;
        }

        var xml = node.OuterXml;
        const string first = "NodeID=\"";
        var start = xml.IndexOf(first, StringComparison.Ordinal) + first.Length;
        var end = xml.IndexOf("\"", start, StringComparison.Ordinal);
        return xml.Substring(start, (end - start));
    }
}
我从ICommonStructureServices获得的结构看起来像,但包含更多的团队和Sprint:

<?xml version="1.0" encoding="utf-8"?>
<Nodes xmlns="">
    <Node NodeID="vstfs:///Classification/Node/43eaa612-c4b1-4043-bbd6-62f56387a7c8" Name="Iteration" Path="\coresystems\Iteration" ProjectID="vstfs:///Classification/TeamProject/4f1ea3c6-5306-4671-b806-8c2df536d218" StructureType="ProjectLifecycle">
        <Children>
            <Node NodeID="vstfs:///Classification/Node/6c123a22-c647-489a-a683-ca6a5bb19f92" Name="Team01" ParentID="vstfs:///Classification/Node/43eaa612-c4b1-4043-bbd6-62f56387a7c8" Path="\coresystems\Iteration\Team01" ProjectID="vstfs:///Classification/TeamProject/4f1ea3c6-5306-4671-b806-8c2df536d218" StructureType="ProjectLifecycle">
                <Children>
                    <Node NodeID="vstfs:///Classification/Node/27efc3cf-270f-463b-9aec-1569d7eaec8a" Name="Sprint1" ParentID="vstfs:///Classification/Node/6c123a22-c647-489a-a683-ca6a5bb19f92" Path="\coresystems\Iteration\Team01\Sprint1" ProjectID="vstfs:///Classification/TeamProject/4f1ea3c6-5306-4671-b806-8c2df536d218" StructureType="ProjectLifecycle" />
                    <Node NodeID="vstfs:///Classification/Node/987b4bae-83ea-4f6f-beba-697ab8bb039f" Name="Sprint2" ParentID="vstfs:///Classification/Node/6c123a22-c647-489a-a683-ca6a5bb19f92" Path="\coresystems\Iteration\Team01\Sprint2" ProjectID="vstfs:///Classification/TeamProject/4f1ea3c6-5306-4671-b806-8c2df536d218" StructureType="ProjectLifecycle" />
                </Children>
            </Node>
        </Children>
    </Node>
</Nodes>

现在,IterationTreeItem类如下所示:

public static IterationTreeItem GetIterationTree()
{
    var structures = TfsShared.Instance.CommonStructureService.ListStructures(TfsShared.Instance.ProjectInfo.Uri);
    var iterationNode = structures.First(_ => _.Name == "Iteration");

    var rawIterationTree = TfsShared.Instance.CommonStructureService.GetNodesXml(new[] { iterationNode.Uri }, true);
    var iterationTree = rawIterationTree.FirstChild;

    var teams = TfsShared.Instance.AllTeams.ToList();

    var configs = TfsShared.Instance.TeamSettingsConfigurationService
                     .GetTeamConfigurations(teams.Select(_ => _.Identity)
                                                 .Select(_ => _.TeamFoundationId));

    var backLogPaths = configs.Select(_ => _.TeamSettings.BacklogIterationPath)
                                  .OrderBy(_ => _)
                                  .Distinct()
                                  .ToArray();

    var fullTree = new IterationTreeItem(iterationTree);

    var iterationList = IterationTreeItem.Flatten(fullTree).ToList();

    IterationTreeItem.SetBackLogsOrSprints(iterationList, backLogPaths);
    return fullTree;
}
[DebuggerDisplay("{CleanIterationPath,nq}")]
public class IterationTreeItem
{
    private readonly List<IterationTreeItem> _children = new List<IterationTreeItem>();

    public IterationTreeItem(XmlNode node)
    {
        if (node != null)
        {
            XmlNode = node;

            var nodeId = GetNodeId(node);

            NodeInfo = TfsShared.Instance.CommonStructureService.GetNode(nodeId);
            if (node.FirstChild != null)
            {
                var children = node.FirstChild.ChildNodes.OfType<XmlNode>()
                                   .Select(_ => new IterationTreeItem(_, this))
                                   .ToArray();

                Children.AddRange(children);
            }
        }
    }

    private IterationTreeItem(XmlNode node, IterationTreeItem parent)
        : this(node)
    {
        Parent = parent;
    }

    public List<IterationTreeItem> Children
    {
        get { return _children; }
    }

    public string CleanBacklogPath
    {
        get
        {
            var parts = CleanIterationPath.Split('\\').ToArray();
            return string.Join("\\", parts.Take(Math.Max(parts.Length - 1, 1)));
        }
    }

    public string CleanIterationPath
    {
        get
        {
            if (NodeInfo != null)
            {
                var notStartedWithSlashes = NodeInfo.Path.Substring(1);
                return notStartedWithSlashes.Replace("\\Iteration", string.Empty);
            }
            return string.Empty;
        }
    }
    public bool? IsProductBackLogIteration { get; private set; }

    public bool? IsSprintIteration { get; private set; }

    public NodeInfo NodeInfo { get; private set; }

    public IterationTreeItem Parent { get; private set; }

    public XmlNode XmlNode { get; private set; }

    public static IEnumerable<IterationTreeItem> Flatten(IterationTreeItem item)
    {
        yield return item;
        foreach (var childChild in item.Children.SelectMany(Flatten))
        {
            yield return childChild;
        }
    }

    public static void SetBackLogsOrSprints(IEnumerable<IterationTreeItem> items, IEnumerable<string> knownBacklogs)
    {
        var backLogs = knownBacklogs as List<string> ?? knownBacklogs.ToList();
        foreach (var iterationTreeItem in items)
        {
            if (backLogs.Any(_ => _ == iterationTreeItem.CleanIterationPath))
            {
                iterationTreeItem.IsProductBackLogIteration = true;
                iterationTreeItem.IsSprintIteration = false;
            }
            else
            {
                iterationTreeItem.IsProductBackLogIteration = false;
                iterationTreeItem.IsSprintIteration = true;
            }
        }
    }

    private static string GetNodeId(XmlNode node)
    {
        if (node.Attributes != null)
        {
            var otherNodeId = node.Attributes.OfType<XmlAttribute>().First(_ => _.Name == "NodeID").Value;
            return otherNodeId;
        }

        var xml = node.OuterXml;
        const string first = "NodeID=\"";
        var start = xml.IndexOf(first, StringComparison.Ordinal) + first.Length;
        var end = xml.IndexOf("\"", start, StringComparison.Ordinal);
        return xml.Substring(start, (end - start));
    }
}
[DebuggerDisplay(“{CleanIterationPath,nq}”)]
公共类迭代树元素
{
私有只读列表_children=new List();
公共迭代树项(XmlNode节点)
{
如果(节点!=null)
{
XmlNode=node;
var nodeId=GetNodeId(节点);
NodeInfo=TfsShared.Instance.CommonStructureService.GetNode(nodeId);
if(node.FirstChild!=null)
{
var children=node.FirstChild.ChildNodes.OfType()
.Select(=>newiterationtreeitem(x,this))
.ToArray();
childreng.AddRange(Children);
}
}
}
私有IterationTreeItem(XmlNode节点,IterationTreeItem父节点)
:此(节点)
{
父母=父母;
}
公开儿童名单
{
获取{return\u children;}
}
公共字符串路径
{
得到
{
var parts=CleanIterationPath.Split('\\').ToArray();
返回字符串.Join(“\\”,parts.Take(Math.Max(parts.Length-1,1));
}
}
公共字符串CleanIterationPath
{
得到
{
if(NodeInfo!=null)
{
var notStartedWithSlashes=NodeInfo.Path.Substring(1);
返回notStartedWithSlashes.Replace(“\\Iteration”,string.Empty);
}
返回字符串。空;
}
}
public bool?IsProductBackLogIteration{get;private set;}
公共布尔?IsSprintIteration{get;private set;}
公共节点信息节点信息{get;private set;}
公共迭代树项父项{get;私有集;}
公共XmlNode XmlNode{get;private set;}
公共静态IEnumerable展平(迭代树项)
{
收益回报项目;
foreach(item.Children.SelectMany中的var childChild(展平))
{
收益回报子女;
}
}
公共静态void setbacklogsorsprint(IEnumerable items,IEnumerable knownBacklogs)
{
var backLogs=knownBacklogs作为列表??knownBacklogs.ToList();
foreach(项目中的var iterationTreeItem)
{
if(backlog.Any(=>==iterationTreeItem.CleanIterationPath))
{
iterationTreeItem.isProductBackLogieration=true;
iterationTreeItem.IsSprintIteration=false;
}
其他的
{
iterationTreeItem.isProductBackLogieration=false;
iterationTreeItem.IsSprintIteration=true;
}
}
}
私有静态字符串GetNodeId(XmlNode节点)
{
if(node.Attributes!=null)
{
var otherNodeId=node.Attributes.OfType().First(=>quo;.Name==“NodeID”).Value;
返回otherNodeId;
}
var xml=node.OuterXml;
const string first=“NodeID=\”;
var start=xml.IndexOf(first,StringComparison.Ordinal)+first.Length;
var end=xml.IndexOf(“\”,start,StringComparison.Ordinal);
返回xml.Substring(start,(end-start));
}
}

可能的重复只需获取迭代根节点,然后获取它们的子节点即可。比较node.Path并在匹配时返回node.Id。[var rootNodeCollection=workItemStore.Projects[“ProjectName”].IterationRootNodes;]。另一种方法是返回要在查询中签入的工作项列表,然后遍历它们的修订历史记录。如果你有很多东西要检查,我想可能会慢一点。如果没有其他人有更好的样品,我可以做一个样品answer@rerwinRR你给了我一个正确的起点。从技术上讲,我使用
IterationRootNodes.OfType().First().ParentNode
访问最高的节点,因此我可以匹配所有节点,但您为我指出了正确的路径。此实例的单个
节点
类确实包含我要查找的预期ID。如果你正式给出答案,我会给你可能的副本,你可以得到迭代根节点,然后是它们的子节点。比较node.Path并在匹配时返回node.Id。[var rootNodeCollection=workItemStore.Projects[“ProjectName”].IterationRootNodes;]。另一种方法是返回要在查询中签入的工作项列表,然后遍历它们的修订历史记录。如果你有很多东西要检查,我想可能会慢一点。如果没有其他人有更好的样品,我可以做一个样品answer@rerwinRR你给了我一个正确的起点。从技术上讲,我使用
IterationRootNodes.OfType().First().ParentNode
访问最高的节点,因此我可以匹配所有节点,但您为我指出了正确的路径。此实例的单个
节点
类确实包含我要查找的预期ID。如果你正式回答,我会给你荣誉