I wanted to access TFS data via TFS API and WIQL using a custom field in WIQL where clause:
string wiqlQueryDoorsProxy =
"Select * from WorkItems where ([Work Item Type] = 'DoorsProxy' AND [Object Id] = '\" + requirementId + "\')";
where [Object Id] is the custom field. But TFS API gave exception message:
"TF51005: The query references a field that does not exist. The error is caused by «[Object Id]»."
The field definition has name = "Object Id" and reference name = "DoorsTool.DoorsArtifactType.ObjectId". I tried both Object Id and DoorsTool.DoorsArtifactType.ObjectId in the WIQL. Same result.
I changed the code as follows and it worked perfectly:
string wiqlQueryDoorsProxy ="Select * from WorkItems where ([Work Item Type] = 'DoorsProxy' )";
WorkItemCollection witCollectionDoorsProxy = wiStore.Query(wiqlQueryDoorsProxy);
foreach (WorkItem workItemDoorsProxy in witCollectionDoorsProxy)
{
workItemDoorsProxy.Open();
if (workItemDoorsProxy.Fields["Object Id"].OriginalValue.ToString() == requirementId)
{
...
}
}
But now the performance is bad.
What can I do. The problem looks similar to this but still I cannot solve the problem based on that discussion.
The way way is to create the query that you want in visual studio first. Once you have It working you can "save as" to local disk and open It in notepad. You can just copy the query from there.
Related
We are using TFS2010.
We have a solution - developed by IBM - that synchronizes data between DOORS and TFS. This solution has created proprietary work items (DoorsProxy) with some proprietary fields DoorsTool.DoorsArtifactType.Module.
I think this question is not specific for Doors but for proprietary fields in general.
We have encountered the following problem:
We used the TFS SDK and WIQL language to access the DoorsProxy Work Item. The standard fields can be accessed but not the Doors proprietary fields. We have used e.g. following query
Select ID, Title, [Work Item Type], [DoorsTool.DoorsArtifactType.Module]
from WorkItems where ([Work Item Type] = 'DoorsProxy' ) order by Title;
But we receive error
TF51005: The query references a field that does not exist. The error is caused by «[DoorsTool.DoorsArtifactType.Module]».
We have tried other syntaxes, other fields and also deleted cache as proposed somewhere but with no success. We have checked field attribute definitions using ProcessEditor etc.
Can you tell whether there is a workaround for this issue?
I made a workaround. I changed
Select ID, Title, [Work Item Type], [DoorsTool.DoorsArtifactType.Module]
from WorkItems where ([Work Item Type] = 'DoorsProxy' ) order by Title;
to
Select * from WorkItems where ([Work Item Type] = 'DoorsProxy' ) order by Title
I changed the C# code to:
string wiqlQueryDoorsProxy =
"Select * from WorkItems where ([Work Item Type] = 'DoorsProxy' ) order by Title";
WorkItemCollection witCollectionDoorsProxy = wiStore.Query(wiqlQueryDoorsProxy);
foreach (WorkItem workItemDoorsProxy in witCollectionDoorsProxy)
{
Console.WriteLine("ID: {0}", workItemDoorsProxy.Id);
Console.WriteLine("Module: {0}", workItemDoorsProxy.Fields["Module"].OriginalValue);
}
I use SqlExecute activity of Build Extension
I wish pass params in arguments of my activity
But my problem is Te parameters are not injected into the SQL script, can you help me please. have you used SqlExecute activity?
Parameters Section in editor, in my build designer of template tfs / wwf :
New String(5) {
"BackupFilePath = F:\MSSQL10.IS_CLTLIVE_DE\DUMP\ClearProdDump\CP.dmp",
"LogicalDataFile = CP_Data01",
"DataFilePath = F:\MSSQL10.IS_CLTLIVE_DE\data\",
"LogicalLogFile = CP_TLog01",
"LogFilePath = F:\MSSQL10.IS_CLTLIVE_DE\log\",
"DatabaseName = AghilasCP_Tmp"
}
My Script.sql
IF EXISTS (SELECT name FROM sys.databases WHERE name = $(DatabaseName ))
Reading the code of that activity it seems that you need to specify the parameters as
New String(5) {
"#BackupFilePath='F:\MSSQL10.IS_CLTLIVE_DE\DUMP\ClearProdDump\CP.dmp'",
"#LogicalDataFile='CP_Data01'",
"#DataFilePath='F:\MSSQL10.IS_CLTLIVE_DE\data\'",
"#LogicalLogFile='CP_TLog01'",
"#LogFilePath='F:\MSSQL10.IS_CLTLIVE_DE\log\'",
"#DatabaseName='AghilasCP_Tmp'"
}
And the statement as
IF EXISTS (SELECT name FROM sys.databases WHERE name = #DatabaseName)
With no spaces around the '=', with a unique name as a parameter name, this scares me a bit, I'd personally have written built this activity differently, and with quotes around the parameter value either in the parameter array or in the SQL code.
Is there a way to programmatically access the "Kanban Column" for a WorkItem using the TFS 2012 API?
Using the Scrum 2.2 template, the history of a Bug or Product Backlog Item shows "[MyProject\MyTeam] Kanban Column" as a changed field whenever a work item is dragged between Kanban columns on the Board, but the field is not accessible when specifically retrieving a work item through the TFS API.
It also shows up as a changed field in the WorkItemChangedEvent object when implementing the ProcessEvent method on the Microsoft.TeamFoundation.Framework.Server.ISubscriber interface.
Workaround:
A coworker found a blogpost about creating a read-only custom field to persist the value of the Kanban Column, taking advantage of the WorkItemChangedEvent to capture the latest value. It is then possible to query on this column. One problem with this approach is that only a single team's Kanban Column can be tracked.
Update:
According to this blogpost, the Kanban Column is not a field, rather a "WIT Extension". This may help lead to an answer.
I've found a way to read the value using the TFS 2013 API, inside the ISubscriber.ProcessEvent method:
var workItemId = 12345;
var extService = new WorkItemTypeExtensionService();
var workItemService = new WorkItemService();
var wit = workItemService.GetWorkItem(requestContext, workItemId);
foreach (var wef in extService.GetExtensions(requestContext, wit.WorkItemTypeExtensionIds))
{
foreach (var field in wef.Fields)
{
if (field.LocalName == "Kanban Column" || field.LocalName == "Backlog items Column")
{
// Access the new column name
var columnName = wit.LatestData[field.Field.FieldId];
}
}
}
If you are prepared to dig into the database you can mine this information out. I don't fully understand the modelling of the teams in TFS yet but first you need to work out which field id the team of interest is storing the Kanban state in as follows (TFS 2012):
USE Tfs_DefaultCollection
SELECT TOP(10)
MarkerField + 1 as FieldId,*
FROM tbl_WorkItemTypeExtensions with(nolock)
JOIN tbl_projects on tbl_WorkItemTypeExtensions.ProjectId = tbl_projects.project_id
WHERE tbl_projects.project_name LIKE '%ProjectName%
Then replace XXXXXXXX below with the FieldId discovered above
SELECT TOP 1000
wid.Id,
wia.State,
wid.StringValue as Kanban,
wia.[Work Item Type],
wia.Title,
tn.Name as Iteration
FROM tbl_WorkItemData wid with(nolock)
JOIN WorkItemsAre wia on wia.ID = wid.Id
JOIN TreeNodes tn on wia.IterationID = tn.ID
WHERE FieldId = XXXXXXXX and RevisedDate = '9999-01-01 00:00:00.000'
ORDER BY Id
I am not familiar with the Scrum 2.2 template, but the works are the same for CMMI or Scrum templates when it comes to TFS Work Item tracking.
Try something like this:
public string GetKanbanColumn(WorkItem wi)
{
if (wi != null)
{
return wi["Kanban"].ToString();
}
return string.Empty;
}
Depending on the actual name of the column, specified in the Work Item Template XML file. Hope this helps.
I want to know how I can update the field of my bug workitem. Suppose I need to change title of my bug workitem and after doing that I should get one pop up message box that my title field has changed without using email alerts? This is the query to select the workitem of a particular team project:
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection
(new Uri("server url"));
var service = tfs.GetService<WorkItemStore>();
var qText = String.Format(#"SELECT [System.WorkItemType],
[System.Title], [System.Description], [System.Reason]
FROM WorkItems WHERE [System.TeamProject] = {0}", "'Demo1'");
I want to know the update query for changing the particular field.
Have you tried something like:
Dim workItemStore as WorkItemStore = tfs.GetService(Of WorkItemStore)()
Dim wi as WorkItem = workItemStore.GetWorkItem(workItemNumber)
wi.Fields("System.Title").Value = "Foo Title"
wi.Save()
I don't think WIQL supports dml commands. You are probably going to have to use the object model to do this: http://msdn.microsoft.com/en-us/library/bb130323.aspx
I have few workitems which contain custom field called "Reference ID"
is it possible to query using wiql on this custom field.
Currently I am using the following approach:
//foreach project in TFS
//form the wiql
WorkItemCollection workItemCollection = workItemStore.Query(
" SELECT [System.Id], [System.WorkItemType]," +
" [System.State], [System.AssignedTo], [System.Title] " +
" FROM WorkItems " +
" WHERE [System.TeamProject] = '" + tfsProject.Name +
"' ORDER BY [System.WorkItemType], [System.Id]");
//run a loop against the result set
//if workitem.Fields["Reference ID"]=required value
//do some tasks on this workitem
this approach is taking quite sometime since there are more than 1000 results.
my question:
is it possible to add custom field also as a filter condition in the above query
Yes. You use the field name that's associated with the item. You can get this using the Process Explorer (TFS Power Tools) and opening the WorkItemType.
Here's an example we use today
Select Id from WorkItems where ([xxx.Ticket.OriginalTicketID] = '12345');
If you do not have access to TFS Power Tools or the ability to install it, then you can also use the DisplayForm property of the Work Item Object.
myItem = Workitem.GetWorkItem("12345")
myItem.DisplayForm
DisplayForm returns an XML containing all the Field Names and Properties. You could look up the XML by label and get the corresponding Control FieldName.
myItem.Fields.Item("Custom.FieldName")
Sure, just add the name of the custom field.