【发布时间】:2015-03-12 01:04:04
【问题描述】:
我的任务是将工作项从一个 TFS 项目重新定位到一个 TFS 集合中的另一个项目。所有历史记录和日期必须与原始项目相同。我读了很多资料,做了很多工作。我几乎完成了任务,但发现了一个关键问题。保存从原始项目复制的新项目后,我在修订中丢失了附件。因此,我只能重新定位项目一次,下次尝试附件将丢失。
有我复制项目的方法:
首先我阅读了关于更改创建日期和更改日期的文章:TFS API Change WorkItem CreatedDate And ChangedDate To Historic Dates。
然后我有下一个代码:
var type = project.WorkItemTypes[itemToCopy.Type.Name];
var newWorkItem = new WorkItem(type);
List<Revision> revisions = item.Revisions.Cast<Revision>().OrderBy(r => r.Index).ToList();
var firstRevision = revisions.First();
revisions.Remove(firstRevision);
SetFields(newWorkItem, firstRevision.Fields, includeAreas);
result = Save(newWorkItem);
if (result != string.Empty)
throw new Exception(result);
newWorkItem = tfsManager.GetWorkItemStore().GetWorkItem(newWorkItem.Id);
var changed = firstRevision.Fields.Cast<Field>().First(f => f.ReferenceName == "System.ChangedDate").Value;
var created = firstRevision.Fields.Cast<Field>().First(f => f.ReferenceName == "System.CreatedDate").Value;
var changedDate = (DateTime)changed;
var createdDate = (DateTime)created;
newWorkItem.Fields["System.CreatedDate"].Value = createdDate;
newWorkItem.Fields["System.ChangedDate"].Value = changedDate.AddSeconds(1);
result = Save(newWorkItem);
if (result != string.Empty)
throw new Exception(result);
var attachments = firstRevision.Attachments.Cast<Attachment>().ToList();
var attachMap = new Dictionary<int, Attachment>();
if (attachments.Count > 0)
AddAttachments(newWorkItem, firstRevision.Attachments.Cast<Attachment>().ToList(), attachMap);
else
{
result = Save(newWorkItem);
if (result != string.Empty)
throw new Exception(result);
}
ApplyRevisions(newWorkItem, revisions, attachMap, includeAreas);
return newWorkItem;
“SetFields”方法将所有可编辑字段从原始工作项复制到新工作项。
“Save”方法只是简单地保存工作项并在保存过程中收集有关错误的所有信息。
“ApplyRevisions”方法简单地枚举所有修订并复制字段和附件。它看起来像:
private void ApplyRevisions(WorkItem toItem,
List<Revision> revisions, Dictionary<int,
Attachment> attachMap,
bool includeAreas)
{
foreach (var revision in revisions.OrderBy(r => r.Index))
{
SetFields(toItem, revision.Fields, includeAreas);
AddAttachments(toItem, revision.Attachments.Cast<Attachment>().ToList(), attachMap);
AddChangesetLinks(toItem, revision.Links.Cast<Link>().ToList());
var result = Save(toItem);
if (result != string.Empty)
{
SetFields(toItem, revision.Fields, includeAreas);
result = Save(toItem);
if (result != string.Empty)
{
throw new Exception(result);
}
}
}
}
主要是我如何复制附件:
private void AddAttachments(WorkItem item, IList<Attachment> attaches, Dictionary<int, Attachment> attachMap)
{
var guid = Guid.NewGuid();
var currentAttaches = item.Attachments.Cast<Attachment>().ToList();
var files = new List<string>();
try
{
item.Open();
foreach (var attach in attaches)
{
if (attachMap.ContainsKey(attach.Id))
{
var id = attachMap[attach.Id].Id;
if (currentAttaches.Any(a => a.Id == id))
continue;
}
var bytes = tfsManager.TfsWebClient.DownloadData(attach.Uri);
var tempFile = CreateFileName(guid, attach.Name);
files.Add(tempFile);
if (bytes != null && bytes.Length > 0)
File.WriteAllBytes(tempFile, bytes);
else
{
File.Create(tempFile).Dispose();
}
var attachInfo = new AttachmentInfo(tempFile);
attachInfo.FieldId = 50;
attachInfo.CreationDate = attach.CreationTimeUtc;
//attachInfo.LastWriteDate = attach.LastWriteTimeUtc;
attachInfo.Comment = attach.Comment;
//attachInfo.AddedDate = attach.AttachedTimeUtc;
var newAttach = Attachment.MakeAttachment(item, attachInfo);
item.Attachments.Add(newAttach);
if (!attachMap.ContainsKey(attach.Id))
attachMap[attach.Id] = newAttach;
}
foreach (var attach in currentAttaches)
{
var id = attachMap.First(pair => pair.Value.Id == attach.Id).Key;
if (attaches.All(a => a.Id != id))
{
item.Attachments.Remove(attach);
}
}
var result = Save(item);
if (result != string.Empty)
throw new Exception(result);
}
finally
{
if (files.Count > 0)
{
foreach (var file in files)
{
File.Delete(file);
}
RemoveTempFolder(guid);
}
}
}
复制项目并从属性“修订”中的 TFS 属性“附件”中检索它后为空。我想,问题出在不同的日期......但不知道如何解决...... 抱歉,代码量很大。这是我在这里的第一个问题。
附: 我对这个问题进行了更深入的研究,发现这个问题在 AttachmentInfo 的 AuthorizedAddedDate 中。在填写附件的过程中,有这个日期和特定修订的ChangeDate的比较。见以下代码:
DateTime asof = (DateTime) changedDate;
foreach (LinkInfo linkInfo in this.m_linksData)
{
if (linkInfo.AuthorizedAddedDate <= asof && asof < linkInfo.AuthorizedRemovedDate)
yield return linkInfo;
}
ChangedDate 我们可以更改,我在处理修订期间更改它。不幸的是,我不知道如何更改AttachmentInfo的AuthorizedAddedDate...即使我更改它,在下一次加载工作项后该值是相同的...似乎禁止更改此值(
【问题讨论】:
-
你找到解决办法了吗?
标签: c# tfs attachment