結局のところ、マネージ 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 パッケージの構文はかなり単純です。注意すべきことの 1 つは、内部型が double であっても、エフォート値 (float) を明示的に文字列に変換する必要があることです。(ここで何か間違ったことをしたかもしれませんが、最終結果は私が望んでいたものでした。)
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;
}
最後に、Web サーバーを呼び出して一括更新を行い、すべての作業項目を変更します。
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);
}