private XmlDocument CreateAttachmentDescriptionDoc(TfsMigrationFileAttachment f, string revision) { Debug.Assert(!string.IsNullOrEmpty(revision)); XmlDocument migrationActionDetails = new XmlDocument(); XmlElement root = migrationActionDetails.CreateElement("WorkItemChanges"); root.SetAttribute("WorkItemID", XmlConvert.ToString(WorkItem.Id)); root.SetAttribute("Revision", revision); root.SetAttribute("WorkItemType", WorkItem.Type.Name); migrationActionDetails.AppendChild(root); XmlElement c = migrationActionDetails.CreateElement("Attachment"); c.SetAttribute("Name", f.Name); c.SetAttribute("Length", XmlConvert.ToString(f.Length)); c.SetAttribute("UtcCreationDate", XmlConvert.ToString(f.UtcCreationDate, XmlDateTimeSerializationMode.Unspecified)); c.SetAttribute("UtcLastWriteDate", XmlConvert.ToString(f.UtcLastWriteDate, XmlDateTimeSerializationMode.Unspecified)); XmlElement v = migrationActionDetails.CreateElement("Comment"); v.InnerText = f.Comment; c.AppendChild(v); root.AppendChild(c); return(migrationActionDetails); }
internal void ComputeAttachmentDelta( ChangeGroupService changeGroupService, DateTime waterMarkChangeStartTime, ITranslationService translationService, Guid sourceId, List <ChangeGroup> groups) { List <TfsMigrationFileAttachment> files = new List <TfsMigrationFileAttachment>(); if (WorkItem.Attachments.Count > 0) { List <Revision> revsToBeSynced = FindUnsyncedRevisions(waterMarkChangeStartTime, translationService, sourceId, null); bool hasAttachmentChanges = false; foreach (Revision rev in revsToBeSynced) { if (rev.Index == 0 && (int)rev.Fields[CoreField.AttachedFileCount].Value > 0) { hasAttachmentChanges = true; break; } if (rev.Index > 0) { int currAttchCount = (int)rev.Fields[CoreField.AttachedFileCount].Value; Revision prevRev = rev.WorkItem.Revisions[rev.Index - 1]; int prevAttchCount = (int)prevRev.Fields[CoreField.AttachedFileCount].Value; if (currAttchCount != prevAttchCount) { hasAttachmentChanges = true; break; } } } if (!hasAttachmentChanges) { return; } foreach (Attachment attachment in WorkItem.Attachments) { if (attachment.AttachedTimeUtc <= waterMarkChangeStartTime || !attachment.IsSaved) { continue; } files.Add(new TfsMigrationFileAttachment(attachment)); } } Guid changeActionId = WellKnownChangeActionId.AddAttachment; ChangeGroup changeGroup = changeGroupService.CreateChangeGroupForDeltaTable( string.Format("{0}:{1}", WorkItem.Id, "Attachments")); foreach (TfsMigrationFileAttachment attachmentFile in files) { XmlDocument migrationActionDetails = CreateAttachmentDescriptionDoc(attachmentFile, WorkItem.Rev.ToString()); changeGroup.CreateAction( changeActionId, attachmentFile, WorkItem.Id.ToString(), "", "0", "", WellKnownContentType.WorkItem.ReferenceName, migrationActionDetails); } // VERY IMPORTANT: use the RelatedArtifactsStore to detect detailed attachment changes WorkItemAttachmentStore store = new WorkItemAttachmentStore(sourceId); List <FileAttachmentMetadata> additionalAttachmentToDelete; store.UpdatePerItemAttachmentChangesByCheckingRelatedItemRecords( WorkItem.Id.ToString(), changeGroup, out additionalAttachmentToDelete); foreach (FileAttachmentMetadata attch in additionalAttachmentToDelete) { TfsMigrationFileAttachment attachmentFile = new TfsMigrationFileAttachment(attch); XmlDocument migrationActionDetails = CreateAttachmentDescriptionDoc(attachmentFile, WorkItem.Rev.ToString()); changeGroup.CreateAction( WellKnownChangeActionId.DelAttachment, attachmentFile, WorkItem.Id.ToString(), "", "0", "", WellKnownContentType.WorkItem.ReferenceName, migrationActionDetails); } groups.Add(changeGroup); }