WorkItem.Links.Contains() 它有什么作用?

发布于 2024-12-11 04:56:46 字数 382 浏览 2 评论 0原文

如果我这样做:

RelatedLink newLink = new RelatedLink(linkTypeEnd, id);
if (workItem.Links.Contains(newLink)) return;
workItem.Links.Add(newLink);

它仍然会在 Add 方法上崩溃并出现 ValidationException,表明该链接已在集合中。

TF237099:工作项链接重复。

那么 Contains 真正检查的是什么?引用相等?肯定不是吗?

有人对如何处理这个问题有一些建议吗?我正在编写一个工具来将需求从众所周知的工具迁移到 TFS。

If I do:

RelatedLink newLink = new RelatedLink(linkTypeEnd, id);
if (workItem.Links.Contains(newLink)) return;
workItem.Links.Add(newLink);

It still crashes on the Add method with a ValidationException, stating that the link is already in the collection.

TF237099: Duplicate work item link.

So what is the Contains really checking? reference equality? surely not?

Anyone got some tips on how to handle this? I'm writing a tool to migrate Requirements from a well known tool to TFS.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空城仅有旧梦在 2024-12-18 04:56:46

因此,您有一个给定的 WorkItem(假设 ID = 1000)&您想要向其中添加一个相关的 WorkItem(假设 ID = 1001)。
简单地查找是

workItem.Links.Add(newLink);

行不通的,因为它会抛出您提供的异常,以防 WI 1001 已经是 WI 1000 的链接。

因此,我们需要在添加之前检查 WI 1001 是否已经在 1000 的链接中。
这是可能的,如下:

WorkItem workItem = workItemStore.GetWorkItem(1000);  

LinkCollection links = workItem.Links;
List<int> relatedWorkItemIds = new List<int>();
foreach (var link in links)
{
   relatedWorkItemIds.Add(((Microsoft.TeamFoundation.WorkItemTracking.Client.RelatedLink) (link)).RelatedWorkItemId);
}

if(relatedWorkItemIds.Contains(1001))
{
   return;
}
else
{
   WorkItemLinkTypeEnd linkTypeEnd = workItemStore.WorkItemLinkTypes.LinkTypeEnds["Child"]; 
   RelatedLink newLink = new RelatedLink(linkTypeEnd, 1001);
   workItem.Links.Add(newLink);
}

努力回答我意识到你直接问“WorkItem.Links.Contains() 它有什么作用?” -->我没有答案。
我希望您能以某种方式利用我上面实现的内容。

So you have a given WorkItem (let's assume with ID = 1000) & you want to add to it a related WorkItem (let's assume with ID = 1001).
Simply going for

workItem.Links.Add(newLink);

won't work, since it throws the exception you 've provided in case WI 1001 is already a link of WI 1000.

So we need to check if WI 1001 is already in the links of 1000 before adding.
This was possible as follows:

WorkItem workItem = workItemStore.GetWorkItem(1000);  

LinkCollection links = workItem.Links;
List<int> relatedWorkItemIds = new List<int>();
foreach (var link in links)
{
   relatedWorkItemIds.Add(((Microsoft.TeamFoundation.WorkItemTracking.Client.RelatedLink) (link)).RelatedWorkItemId);
}

if(relatedWorkItemIds.Contains(1001))
{
   return;
}
else
{
   WorkItemLinkTypeEnd linkTypeEnd = workItemStore.WorkItemLinkTypes.LinkTypeEnds["Child"]; 
   RelatedLink newLink = new RelatedLink(linkTypeEnd, 1001);
   workItem.Links.Add(newLink);
}

Working towards answering I realized that what you directly ask "WorkItem.Links.Contains() what does it do?" --> I have no answer.
I hope you can make somehow use of what I 've implemented above.

°如果伤别离去 2024-12-18 04:56:46

TFS 2013 的行为似乎也没有改变。我遇到了完全相同的问题,这是我在反汇编工具和一点运气的帮助下发现的。

每种类型的链接都以自己的方式实现 Equals 方法。据我所知,它是内部字段的组合,唯一标识链接对象。对于超链接来说,唯一重要的是目标路径。

RelatedLink 在这里有点特殊。首先,它的 Equals 方法比较几个内部字段,特别是源 id 和目标 id。

当您刚刚创建 RelatedLink 对象时,它的目标 id 指向 null。这是有道理的 - 您还没有添加到工作项的链接,并且它不知道它与什么相关。

现在,在代码的第二行中,您调用 Contains 方法,它返回 false。对于新创建的链接始终为 false!这是因为 Contains 方法是通过调用 Equals 方法实现的,该方法通过源 id 和目标 id 比较相关链接。但对于刚刚创建的相关链接,目标 ID 始终为 null。另一方面,workItem.Links 集合中每个对象的目标 ID 永远不会 null

因此,Contains 方法在这种情况下是没有用的。我最终得到了一个丑陋的解决方法,但至少它不需要使用 ID 维护外部集合:

RelatedLink newLink = new RelatedLink(linkTypeEnd, id);

if (workItem.Links.Cast<Link>().FirstOrDefault(l => l.GetType() == typeof(RelatedLink) && ((RelatedLink)l).RelatedWorkItemId == relatedLink.RelatedWorkItemId) == null) 
//if (workItem.Links.Contains(newLink)) 
  return;
workItem.Links.Add(newLink);

因此,我不依赖 Contains 方法,而是检查可能相同并可能导致的数据明确地指出重复关系错误。

PS我知道三年内得到答案没有任何价值。希望这可以帮助其他将工作项从“众所周知的系统”迁移到 TFS 的人:)

It looks like the behavior has not changed for TFS 2013, either. I faced with exactly the same issue, and this is what I found with the help of disassembling tool and a bit of luck.

Each type of link implements the Equals method in its own way. As far as I can tell, it is a combination of internal fields which is uniquely identifies the link object. For Hyperlink, it's only target path that matters.

The RelatedLink is kind of special here. First of all, its Equals method compares several internal fields, in particular, source id and target id.

When you've just created a RelatedLink object, it's target id points to null. And it makes sense - you haven't added a link to a work item, and it doesn't know what it related to.

Now, in the second line of your code, you call Contains method, and it returns false. Always false for a newly created link! That's because the Contains method is implemented the way to call Equals method, which compares related links by source id and target id. But target id is ALWAYS null for a related link which is just created. On the other hand, the target id of every single object in workItem.Links collection is never null.

Hence, Contains method is useless in this case. I ended up with an ugly workaround, but at least it doesn't require maintaining the external collection with IDs:

RelatedLink newLink = new RelatedLink(linkTypeEnd, id);

if (workItem.Links.Cast<Link>().FirstOrDefault(l => l.GetType() == typeof(RelatedLink) && ((RelatedLink)l).RelatedWorkItemId == relatedLink.RelatedWorkItemId) == null) 
//if (workItem.Links.Contains(newLink)) 
  return;
workItem.Links.Add(newLink);

So, instead of relying on Contains method, I check the data which might be identical and might lead to the duplicate relation error explicitly.

P.S. I understand that getting the answer in 3 years has no value. Hopefully, this can help others who migrate work items from "well known systems" to TFS :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文