Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Query for TFS Stored/Saved query by Full path and Query Name (Queries not in 'My Queries' or 'Shared Queries')

Tags:

c#

tfs

I'm trying to access saved TFS queries by their full path (deeper than 'My Queries'/'Shared Queries') , and the query name.

The scenario is that users can add the path to their team directory, and the names of the their work item queries into a config xml file. I read the xml and get the data.

example XML

<Teams>
  <Team name ="MyTeam">
    <Query project="MyProj" queryfolder="Shared Queries/blah/blah2/MyTeamFolder" queryName="MyTeams WorkItems - All Workitems"/>
  </Team>
</Teams>

I'm looking to use the 'queryfolder' and the 'queryName' to find the query in TFS What I have so far, that works for the Root directories ('My Queries'/'Shared Queries'), but I can't figure out how to get something working for deeper paths.

This does not work:

  QueryHierarchy queryRoot = workItemStore.Projects["MyProj"].QueryHierarchy;
                QueryFolder folder = (QueryFolder)queryRoot["Shared Queries/blah/blah2/MyTeamFolder"];
                QueryDefinition query = (QueryDefinition)folder["MyTeams WorkItems - All Workitems"];
                string queryResults = query.QueryText;

This will error out on finding the folder QueryFolder folder = (QueryFolder)queryRoot[".."]

with KeyNotFoundException

changing the folder with 'Shared Queries' or 'My Queries', its able to find the folder, but then would get the same exception when trying to find the Query by its' name. And as expected, if the query is located in the root folder (shared/my queries), it works fine.

So how do I search deeper than just the root folder?

(all internet searches so far have yielded only examples where the root folder is being used)

like image 741
Tdawg90 Avatar asked Sep 26 '22 23:09

Tdawg90


2 Answers

This self-recursive method will find your query from the query tree if it exists:

    static QueryDefinition GetQueryDefinitionFromPath(QueryFolder folder, string path)
    {
        return folder.Select<QueryItem, QueryDefinition>(item =>
        {
            return item.Path == path ?
                item as QueryDefinition : item is QueryFolder ?
                GetQueryDefinitionFromPath(item as QueryFolder, path) : null;
        })
        .FirstOrDefault(item => item != null);
    }

Your example is given, call

  var myquery = GetQueryDefinitionFromPath( (QueryFolder)workItemStore.Projects["MyProj"].QueryHierarchy, "Shared Queries/blah/blah2/MyTeamFolder/MyTeams WorkItems - All Workitems" );
like image 90
BenGra Avatar answered Nov 15 '22 05:11

BenGra


The recursive answer above can work but I had issues with it due to the fact that the item.Path includes the entire path from the root and the path I was passing in did not; resulting in a null value as the final result. I also found that it does a lot of extra work as it touches every folder in the entire tree on its way to your desired folder.

I opted for a simple drill down looking specifically for the nodes I knew would/should be there making the method much more efficient by ignoring all the chaff. I pass in the full path from the root and use the string.Split('/').Skip(1).ToArray() to move past the root node avoiding the KeyNotFoundException since the root does not include itself. I intentionally did not handle the case where the folder was not found since we are in complete control of what we pass in and should only be providing a valid path.

Code is:

    private static QueryFolder GetQueryFolderFromPath(QueryFolder folder, string path)
    {
        var pathNodes = path.Split('/').Skip(1).ToArray();

        foreach(var node in pathNodes)
        {
            folder = (QueryFolder)folder[node];
            if (folder != null && folder.Path.Equals(path))
                break;
        }
        return folder;
    }
like image 28
C. Jones Avatar answered Nov 15 '22 07:11

C. Jones