Запрос ошибок, задач и прочих рабочих элементов
Можно запросить для ошибок, задач и других рабочих элементов и связей между рабочими элементами с помощью одного из методов 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”)
Содержание раздела
Необходимые разрешения
Запрос будет возвращать только те рабочие элементы, для которых имеется разрешение Просмотр рабочих элементов или Просмотр рабочих элементов на этом узле.Обычно эти разрешения предоставлены членам группы Читатели и Авторы для каждого командного проекта.Дополнительные сведения см. в разделе Разрешения Team Foundation Server.
Совет |
---|
Для просмотра сведений языка запросов рабочих элементов, создание запросов с помощью Team Explorer, а затем сохранить их как файлы .wiql.Переименование файлов для использования расширения xml и открыть их в Visual Studio.Найдите элемент wiql чтобы увидеть, как каждый запрос выражается на языке запросов рабочих элементов. |
Язык запросов
Язык запроса рабочего элемента имеет 5 частей.
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] |
Определяет каждый Field, значение которого будет установлено в каждое WorkItem, возвращаемого запросом.Можно указать отображаемое имя или имя ссылки поля.Необходимо использовать квадратные скобкы ([]), если имя содержит пробелы или точки.
Внимание
Можно использовать WorkItem, возвращенное запросом для получения значения Field, даже если запрос не возвратил значение.Если это сделать, то другой круговой путь к серверу.Дополнительные сведения см. в разделе Подкачка значений полей.
|
From WorkItems |
Указывает, должен ли запрос для поиска рабочих элементов или связей между рабочими элементами.
|
Where [Work Item Type] = 'User Story' |
Определяет условие фильтрации для запроса.Дополнительные сведения см. в подразделе Предложение where далее в этом разделе. |
Order By [State] Asc, [Changed Date] Desc |
(Необязательный) определяет способ сортировки WorkItemCollection, возвращаемых запросом. |
AsOf '6/15/2010' |
(Необязательный) определяет historical запрос, указав дату или момента времени, на которой фильтра должны быть применены.Например, этот запрос возвратит все описания функциональности пользователей, которые существовали 15-ого июня 2010.
Примечание
Нельзя создать запросы AsOf в построителе запросов в Visual Studio.При создании запроса (файл .wiq), который включает предложение AsOf, а затем загружает то в Visual Studio, предложение AsOf будет игнорирован.
|
Предложение where
Предложение 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}] |
|
Группа |
(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'
|
Операторы сравнения
Можно использовать операторы в следующей таблице, чтобы указать, как должен связать поле с соответствующим значению.
Оператор запроса |
Описание |
Применимые типы полей |
---|---|---|
= |
Соответствует значению. |
"Число", "Текст", "Дата", "Дерево" |
<> |
Не соответствует значению. |
"Число", "Текст", "Дата", "Дерево" |
> |
Больше, чем значение. |
"Число", "Текст", "Дата" |
< |
Меньше значения. |
"Число", "Текст", "Дата" |
>= |
Больше или равно значению. |
"Число", "Текст", "Дата" |
<= |
Меньше или равно значению. |
"Число", "Текст", "Дата" |
Содержит |
Содержит строку. |
Текст. |
Не содержит |
Не содержит строку. |
Текст. |
В |
Соответствует любому значению в запятая-размежеванном наборе.Например, [System.Id] In (100, 101, 102) найти рабочие элементы, идентификаторы которых 100, 101 и 102. |
"Число", "Текст", "Дата", "Дерево" |
В группе |
Член группы.Группа может быть группой Team Foundation ([Assigned to] In Group [Project]\Contributors) или по категориям рабочего элемента при использовании с полем типа рабочего элемента ([Work Item Type] In Group Requirements).Дополнительные сведения о группах категорий см. в разделе Определение категорий для группирования типов рабочих элементов. |
Текст. |
Не в группе |
Не является членом группы.Дополнительные сведения см. в разделе запись для In Group. |
Текст. |
Всегда |
Совпадения, если поле всегда соответствует значению, то, даже несмотря на то, что значение изменено на другое значение. |
"Текст", "Дата" |
В группе |
Для областей и итераций, совпадения, если рабочий элемент в этом узле или любом один из его дочерних узлов.Дополнительные сведения об областях см. в разделе Создание и изменение областей и итераций и итерациях. |
Дерево |
Не в группе |
Для областей и итераций, совпадения, если рабочий элемент не находится в этом узле или любом один из его дочерних узлов. |
Дерево |
Переменные
Можно использовать переменные в запросах для передачи входной или вычисляемые значения пользователя.Чтобы создать запрос, который включает переменные, создание прототипов в строке запроса с помощью @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.По умолчанию значения даты и времени в запросах для рабочих элементов, интерпретируется как имеющий точность даты.Например, рабочий элемент, создать в любой момент дня 1-ого июня 2010., сопоставил бы условиям фильтра [Created Date] = 6/1/2010. Дополнительные сведения см. в разделе Методы запроса и объект запроса далее в этом разделе и следующей странице веб-сайта Майкрософт: datetime (Transact-SQL). |
Double |
Действительное число, например 0,2 или 3,5. |
GUID |
Символьная строка, которая представляет идентификатор GUID. |
HTML |
Текстовые строки, которые содержат HTML. |
Integer |
32 Разрядное целое число, подписано, например 0, 1, 2 или 34. |
PlainText |
Неформатированное текстовая строка, которая может быть длиннее 255 символов. |
Строка. |
Текстовая строка, содержащая до 255 символов. |
TreePath |
При разрешении разветвление древовидную структуру, например области или итерации. |
Запросы для связей между рабочими элементами
Можно также использовать запросы для поиска ссылок между рабочими элементами.Условия в предложение where может применяться к ссылкам или к любому рабочим элементом, который является источником или целевой объект ссылки.В следующей таблице приведены все различия между этими типами запросов и запросами только для рабочих элементов.
Рабочие элементы |
Связи между рабочими элементами |
|
---|---|---|
Предложение 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, запрос возвращает содержит значения для следующих полей:
Идентификатор
Rev (изменение)
AreaID
IterationID
WorkItemType
Значения полей, указанные в предложении SELECT, возвращаются в страницах.
Примечание |
---|
По умолчанию каждая страница содержит выбранные поля для 50 рабочих элементов.Можно настроить размер страниц с помощью 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.