事实证明,这在使用托管 API 时无法直接完成。使用 Web 服务 API 时,有一个BypassRules
可以设置的属性。
Web 服务 API 需要一个 XML 包,因此难点在于创建它。
首先,像往常一样连接到服务器和集合。
var tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
new Uri(SERVER_URI), new UICredentialsProvider());
tpc.EnsureAuthenticated();
var store = tpc.GetService<WorkItemStore>();
var server = tpc.GetService<WorkItemServer>();
建立连接后,我组装了一个我想要修改的工作项 ID 的列表。就我而言,我需要将所有工作项Efforts
除以 2。
XML 包语法相当简单。需要注意的一点是,我明确需要将我的努力值(浮点数)转换为字符串,即使内部类型是双精度。(我可能在这里做错了什么,但最终结果是我想要的。)
private static StringBuilder GetXmlPackage(WorkItemStore store, IEnumerable<int> workItemIds)
{
var sb = new StringBuilder();
sb.Append("<Package>");
foreach (var id in workItemIds)
{
var item = store.GetWorkItem(id);
var effort = Convert.ToSingle(item.Fields["Effort"].Value) / 2.0f;
sb.AppendFormat("<UpdateWorkItem ObjectType='WorkItem' BypassRules='1' WorkItemID='{0}' Revision='{1}'>", item.Id, item.Rev.ToString());
sb.Append("<Columns>");
sb.AppendFormat("<Column Column='Microsoft.VSTS.Scheduling.Effort' Type='Double'><Value>{0}</Value></Column>", XmlConvert.ToString(effort));
sb.Append("</Columns>");
sb.Append("<InsertText FieldName='System.History' FieldDisplayName='History'>Updated effort.</InsertText>");
sb.Append("</UpdateWorkItem>");
}
sb.Append("</Package>");
return sb;
}
最后要做的是调用网络服务器并进行批量更新以修改所有工作项。
private static void UpdateWorkItems(WorkItemStore store, WorkItemServer server, IEnumerable<int> workItemIds)
{
var sb = GetXmlPackage(store, workItemIds);
var mthe = new MetadataTableHaveEntry[0];
string dbStamp;
IMetadataRowSets rowSets;
XmlElement outElement;
var doc = new XmlDocument();
doc.LoadXml(sb.ToString());
server.BulkUpdate(
WorkItemServer.NewRequestId(),
doc.DocumentElement,
out outElement,
mthe,
out dbStamp,
out rowSets);
}