0

マネージ TFS API を使用して作業項目のフィールドを更新しようとしています。

ただし、特定の状態ではフィールドが読み取り専用としてマークされ (たとえば、Done状態)、その時点で、TFS API を使用している場合でもフィールドを変更できません。IsEditableフィールドが を返すことに気付きましたが、False設定できません。

var effort = Convert.ToSingle(workItem.Fields["Effort"].Value);
workItem.Fields["Effort"].Value = effort / 2.0f;

私のコードは、フィールドが編集可能なすべての状態で機能するため、機能すると確信しています。チーム エクスプローラー UI を使用して作業項目を確認すると、変更が適用され、作業項目の履歴で追跡されていることがわかります。これは、生成されるすべてのレポートにも反映されます。

読み取り専用としてマークされた後、フィールドを変更するにはどうすればよいですか? それは可能ですか?(状態を元に戻してフィールドを編集可能にすることもできますが、これがベロシティとバーンダウン チャートにどのような影響を与えるか分からないため、これは避けたいと考えています。)

4

2 に答える 2

2

結局のところ、マネージ 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);
}
于 2012-08-02T13:42:05.613 に答える
0

知る限り、条件付きでAPIを使用してこれを行うことができます。プロセスが実行されているアカウントは、プロジェクト コレクション サービス アカウントグループに属している必要があります。次に、以下のコードのように BypassRules フラグを設定して WorkIteMStore を作成すると、フィールドを更新できます。

WorkItemStore wis = new WorkItemStore(tpc, WorkItemStoreFlags.BypassRules);

于 2012-10-01T20:02:43.967 に答える