查詢 Bug、工作和其他工作項目
您可以針對 Bug、工作、工作項目的其他工作項目使用其中一 WorkItemStore.Query 方法或 Query 物件之間的型別和連結查詢。這些查詢使用工作項目查詢語言 (WIQL),類似 Transact-SQL。
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(
new Uri("https://server:8080/tfs/DefaultCollection"));
WorkItemStore workItemStore = (WorkItemStore)tpc.GetService(typeof(WorkItemStore));
WorkItemCollection queryResults = workItemStore.Query("
Select [State], [Title]
From WorkItems
Where [Work Item Type] = 'User Story'
Order By [State] Asc, [Changed Date] Desc");
Dim collectionUri As Uri
collectionUri = New Uri("https://Server:8080/tfs/DefaultCollection")
Dim tpc As New TfsTeamProjectCollection(collectionUri)
Dim workItemStore As WorkItemStore
workItemStore = tpc.GetService(Of WorkItemStore)()
Dim queryResults As WorkItemCollection
queryResults = workItemStore.Query(“
Select [State], [Title]
From WorkItems
Where [Work Item Type] = ‘User Story’
Order By [State] Asc, [Changed Date] Desc”)
本主題內容
必要的使用權限
查詢會傳回您有 [檢視工作項目。] 或 [將檢視此節點中的工作項目] 權限的那些工作項目。一般來說,這些允許 [Readers] 和 [參與者] 群組成員的每個 Team 專案的。如需詳細資訊,請參閱Team Foundation Server 使用權限。
![]() |
---|
使用 Team Explorer,若要探索工作項目查詢語言的詳細資料,請建立查詢,然後將它們儲存在 .wiql 檔案。將檔案重新命名使用 .xml 副檔名和開啟它們在 Visual Studio。尋找項目 wiql 查看每個查詢如何使用工作項目查詢語言來表示。 |
查詢語言
工作項目查詢語言包含五個部分。
Select [State], [Title]
From WorkItems
Where [Work Item Type] = 'User Story'
Order By [State] Asc, [Changed Date] Desc
AsOf '6/15/2010'
Select [State], [Title] |
識別 Value 在每 WorkItem 將設定由查詢所傳回的每 Field 。您可以指定顯示名稱或欄位的參考名稱。您必須使用方括弧 ([]),如果名稱包含空白或持續期間。 |
From WorkItems |
指出是否要查詢來尋找工作項目或連結工作項目之間的間距。
|
Where [Work Item Type] = 'User Story' |
指定查詢的篩選準則。如需詳細資訊,請參閱本主題中稍後的WHERE 子句。。 |
Order By [State] Asc, [Changed Date] Desc |
(選擇性) 指定如何排序查詢傳回的 WorkItemCollection 。 |
AsOf '6/15/2010' |
(選擇性) 您可以指出篩選要套用的日期或時間點指定歷史查詢。例如,下列查詢會傳回存在 Hole 年 6 月、日的使用者劇本。 ![]()
您無法在查詢產生器的 AsOf 查詢在 Visual Studio。如果您在 Visual Studio 建立查詢檔 (.wiq) 包含一個 AsOf 子句,然後載入該, AsOf 子句將被忽略。
|
WHERE 子句。
子句為工作項目的位置指定查詢的篩選準則。查詢傳回符合這些條件才能的工作項目。下列範例查詢傳回已啟用,而且已指派給您的使用者劇本。
Where [Work Item Type] = 'User Story'
AND [State] = ‘Active’
AND [Assigned to] = @Me
您可以控制邏輯運算子評估的命令,如果您使用括弧來群組搜尋準則。例如,會傳回或指派給您或您關閉,變更查詢篩選符合下列範例的工作項目:
Where [Work Item Type] = 'User Story'
AND [State] = ‘Active’
AND ( [Assigned to] = @Me
OR [Closed by] = @Me )
下表描述語法 WHERE 子句:
語法 |
範例 |
|
---|---|---|
WHERE 子句 |
Where FilterCondition [Group|{LogicalOperator FilterCondition}] |
|
Group |
(FilterCondition LogicalOperator FilterCondition [LogicalOperator Filter Condition]…) |
([Assigned to] = @Me OR [Created by = @Me]) 邏輯群組的運算子是 AND 和 OR。 |
FilterCondition |
Field ComparisonOperator Value |
[Work Item Type] = ‘Help Topic’ 您可以指定參考名稱或欄位的顯示名稱。如果名稱包含空格或句號,您在方括弧必須用引號括住 ([])。 比較運算子在 比較運算子 後會說明主題。 若為值,您可以指定常值 (「使用者劇本」) 或巨集 (@Me)。 |
值 |
LiteralValue|Variable|Field |
'User Story' |
比較運算子
您可以針對如下表所述使用運算子指定欄位必須如何與對應的值相關聯:
查詢運算子 |
描述 |
欄位的適當資料型別 |
---|---|---|
= |
符合值。 |
號碼、文字、日期、樹狀結構 |
<> |
不符合值。 |
號碼、文字、日期、樹狀結構 |
> |
大於值。 |
號碼、文字、日期 |
< |
的值。 |
號碼、文字、日期 |
>= |
大於或等於值。 |
號碼、文字、日期 |
<= |
小於或等於值。 |
號碼、文字、日期 |
包含 |
包含字串。 |
文字 |
不包含 |
不包含字串。 |
文字 |
In |
比對一個逗號分隔之集合中的任何值。例如, [System.Id] In (100, 101, 102) 尋找 ID 是指定為,的和 102 的工作項目。 |
號碼、文字、日期、樹狀結構 |
在群組中 |
是群組的成員。群組可以是 Team Foundation 群組 ([Assigned to] In Group [Project]\Contributors) 或工作項目分類,當您將它與工作項目類型欄位 ([Work Item Type] In Group Requirements)。如需分類群組的詳細資訊,請參閱定義分類以分組工作項目類型。 |
文字 |
不在群組中 |
不是群組的成員。如需詳細資訊,請參閱 In Group的輸入。 |
文字 |
曾經是 |
遊戲,如果欄位符合,則為值,即使它變更為不同的值。 |
文字、日期 |
在其下 |
對於區域和反覆項目,遊戲,如果工作項目在該節點或其任何子節點。如需區域和反覆項目的詳細資訊,請參閱 建立和修改區域和反覆項目。 |
Tree |
不在其下 |
對於區域和反覆項目,遊戲,如果工作項目無法在該節點或其任何子節點。 |
Tree |
變數
您在查詢中使用變數將使用者輸入傳遞或計算值。使用 @variable,建立包含變數的查詢,在查詢字串中建立預留位置。使用 IDictionary的實作,然後藉由名稱和每個變數的值指派給查詢,方法,如下列範例所示
// Define a query that uses a variable for the type of work item.
string queryString = "Select [State], [Title] From WorkItems Where [Work Item Type] = @Type";
// Set up a dictionary to pass "User Story" as the value of the type variable.
Dictionary<string, string> variables = new Dictionary<string, string>();
variables.Add("Type", "User Story");
// Create and run the query.
Query query = new Query(workItemStore, queryString, variables);
WorkItemCollection results = query.RunQuery();
// Define a query that uses a variable for the type of work item.
Dim queryString As New StringBuilder("SELECT [State], [Title] FROM WorkItems WHERE [WorkItemtype] = @Type")
// Set up a dictionary to pass "User Story" as the value of a type variable.
Dim variables = New Dictionary(Of String, String)
variables.Add("Type", "User Story")
// Create and run the query.
Dim query As New Query(workItemStore, queryString, variables)
WorkItemCollection results = query.RunQuery()
您在查詢中也可以使用 @Me 或 @Today ,但未提供值給這些變數。當這些變數出現在查詢,但沒有傳遞的關聯值。 IDictionary 實作時,變數會評估,如下表所述:
變數 |
使用方式 |
---|---|
@Me |
在包含使用者名稱的欄位會指示目前的使用者。例如,您可以在您啟動的工作項目,如果指定 [Activated by] =@Me。 |
@Today |
表示目前日期。您可以藉著加減天數也修改 @Today 變數。例如,您可以在最後一週啟動的所有項目,如果指定 [Activated Date] > @Today - 7。 |
常值
當您指定每個欄位的值時,值必須符合該欄位的資料型別。Team Foundation 的所有欄位具有下表所列的其中一種資料型別:
資料型別 |
儲存的資料 |
---|---|
DateTime |
datetime 值如所定義 SQL Server。根據預設,查詢中的 DateTime 值的工作項目會將具有日期精確度。例如,隨時建立 Hole 年 6 月一日的日期的工作項目,將符合篩選準則 [Created Date] = 6/1/2010。 本主題和下列網頁的。如需詳細資訊,請參閱之後 查詢方法和查詢物件 Microsoft 網站: DateTime (Transact-SQL). |
Double |
實際數字,例如 0.2 或 3.5。 |
GUID |
表示的 GUID 字串。 |
HTML |
包含 HTML 的文字字串。 |
Integer |
帶正負號的,例如,為,、或 34 帶正負號整數。 |
PlainText |
比範圍字元長度超過的未格式化的文字字串。 |
字串 |
包含範圍字元的文字字串。 |
TreePath |
一個分支的樹狀結構,例如區域或反覆項目。 |
連結的查詢工作項目之間的連結
您也可以使用查詢來尋找工作項目之間的連結。在的條件子句可能套用到連結或屬於來源或連結目標的所有工作項目的位置。下表摘要說明在查詢類型和只有查詢之間的差異工作項目:
工作項目 |
工作項目之間的連結。 |
|
---|---|---|
FROM 子句 |
從 WorkItems |
從 WorkItemLinks |
WHERE 子句 |
[FieldName] = Value |
下列其中一項:
|
模式 |
下列其中一項:
|
|
傳回 |
[ T:Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemCollection ] |
WorkItemLinkInfo 的陣列。 |
下列查詢會傳回使用者劇本及其現用子節點之間的連結。
SELECT [System.Id]
FROM WorkItemLinks
WHERE ([Source].[System.WorkItemType] = 'User Story')
And ([System.Links.LinkType] = 'Child')
And ([Target].[System.State] = 'Active')
mode(MustContain)
查詢方法和查詢物件
使用 WorkItemStore.Query 方法,您可以為工作項目查詢。您也可以識別使用 WorkItemStore.QueryCount 方法,符合查詢,而不需傳回任何工作項目的工作項目數目。
您可以建立 Query 物件定義和執行查詢。
string queryString = "Select [Title] From WorkItems Where [Work Item Type] = 'User Story'"
Query query = new Query(workItemStore, queryString);
int numWorkItems = query.RunCountQuery();
Console.WriteLine("The project collection has " + numWorkItems.ToString() + " user stories.");
Dim queryString As New StringBuilder("Select [Title] FROM WorkItems WHERE [WorkItemType] = 'User Story'"
Dim query As New Query(workItemStore, queryString)
Dim numWorkItems As Int
numWorkItems = query.RunCountQuery()
Console.Writeline("The project collection has " + numWorkItems.ToString() + " user stories.")
非同步查詢
使用 Query.BeginQuery 方法,您可以執行查詢以非同步方式。下列範例執行查詢非同步並在一個非常短的逾時期限之後取消查詢。
// Run the query asynchronously, and time out after 0.05 seconds.
ICancelableAsyncResult callback = query.BeginQuery();
callback.AsyncWaitHandle.WaitOne(50, false);
if (!callback.IsCompleted)
{
callback.Cancel();
Console.WriteLine("The query timed out");
}
else
{
WorkItemCollection nextResults = query.EndQuery(callback);
Console.WriteLine("The project collection has " + nextResults.Count.ToString() + " work items.");
}
Dim callback as ICancelableAsyncResult
callback = query.RunQuery()
callback.AsyncAWaitHandle.WaitOne(50, False)
If Not (callback.IsCompleted)
Then
callback.Cancel()
Console.Writeline("The query timed out")
Else
Dim nextResults As WorkItemCollection = query.EndQuery(callback)
Console.Writeline("The project collection has " + nextResults.Count.ToString() + " work items.")
End If
欄位值分頁
查詢傳回的 WorkItemCollection 包含下列欄位的值:
ID
(修正)
AreaID
IterationID
WorkItemType
您在 Select 子句中指定欄位的值在網頁傳回。
![]() |
---|
根據預設,每個頁面包含一個工作項目的選取的欄位。使用 WorkItemCollection.PageSize,您可以調整頁面的大小。 |
您可以減少來回存取伺服器藉由選取您的程式碼所使用的所有欄位。下列程式碼會執行查詢的往返和一往返都會傳回新網頁存取標頭的網頁。
WorkItemCollection results = WorkItemStore.Query(
"SELECT Title FROM Workitems WHERE (ID < 1000)");
foreach (WorkItem item in results)
{
Console.WriteLine(item.Fields["Title"].Value);
}
如果您的程式碼存取您在 Select 子句中沒有指定的欄位,該欄位加入至分頁欄位。其他往返執行重新整理該網頁包含該欄位的值。
查詢語法 (EBNF)
擴充巴克斯格式 (EBNF) 處於精簡且明確的方式描述語言語法的中繼語言。這個程式碼區塊使用 EBNF 描述工作項目查詢語言 (WIQL) 語法。
如果您不熟悉,請參閱 EBNF 工作項目查詢語言 (WIQL) 的替代的說明 Syntax for the Work Item Query Language的。
<select> ::= <flat-select> | <one-hop-select> | <recursive-select>
<flat-select> ::= select <field list>
from workitems
[ where <expression> ]
[ order by <order by field list> ]
[ asof <datetime> ]
<one-hop-select> ::= select <field list>
from workitemlinks
[ where <one-hop-link-expression> <source-expression> <target-expression> ]
[ order by <source-target order by field list> ]
[ asof <datetime> ]
mode( mustcontain | maycontain | doesnotcontain )
<recursive-select> ::= select <field list>
from workitemlinks
where <recursive-link-expression> [ and <source-expression> <target-expression> ]
mode ( recursive | returnmatchingchildren )
<expression> ::= <expression4>
<expression4> ::= <expression3> [ or <expression4> ]
<expression3> ::= <expression2> [ and <expression3> ]
<expression2> ::= {[ not | ever ] <expression2> }
| <expression1>
<expression1> ::= <conditional expression>
<conditional expression> ::= { '(' <expression> ')' } | <field reference name> <conditional operator> <value> | <field reference name> [not] in '(' <value list> ')'
<value> ::= <number>
| <string>
| <datetime>
<value list> ::= <value> [ ',' <value list> ]
<conditional operator> ::= { '=' | '<>' | '<' | '<=' | '>' | '>=' }
| { [ever] [not] { like | under }}
<link operator> ::= '=' | '<>'
<field list> ::= <field name> [ ',' <field list> ]
<order by field list> ::= <order by field> [ ',' <order by field list> ]
<source-target order by field list> ::= [ <source> |<target> ] <order by field> [ ',' <source-target order by field list> ]
<order by field> ::= <field name> [ 'asc' | 'desc' ]
<number> ::= [ '-' ] <digit>* [ '.' [ <digit>* ]] [ { e | E } [ '-' ] <digit>* ]
<string> ::= { ''' { <anychar except '''> | '''' }* ''' }
| { '"' { <anychar except '"'> | '""' }* '"' }
<datetime> ::= <string>
<source> ::= '[source].'
<target> ::= '[target].'
<one-hop-link-expression> ::= <one-hop-link-expression4> | ''
<one-hop-link-expression4> ::= <one-hop-link-expression3> [ or <one-hop-link-expression4> ]
<one-hop-link-expression3> ::= <one-hop-link-expression2> [ and <one-hop-link-expression3> ]
<one-hop-link-expression2> ::= {[ not | ever ] <one-hop-link-expression2>}
| <one-hop-link-expression1>
<one-hop-link-expression1> ::= <conditional-link-expression>
<conditional-link-expression> ::= { '(' <one-hop-link-expression> ')' } | <linktype-field> <link operator> <linktype-name><linktype-direction> | <linktype-field> [not] 'in (' <linktype list> ')'
<recursive-link-expression> ::= <linktype-field> '=' <linktype-name>'-forward'
<linktype list> ::= <linktype-name><linktype-direction> [, <linktype-name><linktype-direction>]
<linktype-direction> ::= '-forward' | '-reverse'
<source-expression> ::= <source-expression4> | ''
<source-expression4> ::= <source-expression3> [ or <source-expression4> ]
<source-expression3> ::= <source-expression2> [ and <source-expression3> ]
<source-expression2> ::= {[ not | ever ] <source-expression2> }
| <source-expression1>
<source-expression1> ::= <conditional-source-expression>
<conditional-source-expression> ::= { '(' <source-expression> ')' } | <source><field reference name> <conditional operator> <value> | <source><field reference name> [not] in '(' <value list> ')'
<target-expression> ::= <target-expression4> | ''
<target-expression4> ::= <target-expression3> [ or <target-expression4> ]
<target-expression3> ::= <target-expression2> [ and <target-expression3> ]
<target-expression2> ::= {[ not | ever ] <target-expression2> }
| <target-expression1>
<target-expression1> ::= <conditional-target-expression>
<conditional-target-expression> ::= { '(' <target-expression> ')' } | <target><field reference name> <conditional operator> <value> | <target><field reference name> [not] in '(' <value list> ')'
<linktype-field> ::= '[System.Links.LinkType] = '
<select> ::= select <field list>
from workitems
[ where <expression> ]
[ order by <order by field list> ]
[ asof <datetime> ]
<expression> ::= <expression4>
<expression4> ::= <expression3> [ or <expression4> ]
<expression3> ::= <expression2> [ and <expression3> ]
<expression2> ::= {[ not | ever ] <expression2> }
| <expression1>
<expression1> ::= <conditional expression>
<conditional expression> ::= { '(' <expression> ')' } | <field reference name> <conditional operator> <value> | <field reference name> [not] in '(' <value list> ')'
<value> ::= <number>
| <string>
| <datetime>
<value list> ::= <value> [ ',' <value list> ]
<conditional operator> ::= { '=' | '<>' | '<' | '<=' | '>' | '>=' }
| { [ever] [not] { like | under }}
<field list> ::= <field name> [ ',' <field list> ]
<order by field list> ::= <field name> [ asc | desc ] [ ',' <order by field list> ]
<number> ::= [ '-' ] <digit>* [ '.' [ <digit>* ]] [ { e | E } [ '-' ] <digit>* ]
<string> ::= { ''' { <anychar except '''> | '''' }* ''' }
| { '"' { <anychar except '"'> | '""' }* '"' }
<datetime> ::= <string> Insert section body here.