TFS query on HTML-field for empty value - tfs-2015

I want to get with a wiql query all workitem that have an empty HTML field.
Is there a way to do so?

To query out those work items who have empty HTML field like Description, using the query from TFS web page couldn't do that. There's no operator like "isEmpty or isNotEmpty" to use. Here is a uservoice about your request, and according to it, this feature is under review now.
As a workaround, you could use Excel to filter those work items. Write a simple query and export those work items to Excel. Then use the filter In Excel.
You could also use TFS object model api to get those empty field workitems, here is an example:
WorkItemStore workItemStore = teamProjectCollection.GetService<WorkItemStore>();
string queryString = "Select [State], [Title],[Description] From WorkItems Where [Work Item Type] = 'User Story' and [System.TeamProject] = 'TeamProjectName'";
// Create and run the query.
Query query = new Query(workItemStore, queryString);
WorkItemCollection witCollection = query.RunQuery();
foreach (WorkItem workItem in witCollection)
{
//check if the field is empty
if(workItem.Fields["Description"].Value.ToString() == string.Empty || workItem.Fields["Description"].Value.ToString() == "")
{
Console.WriteLine(workItem.Title);
}
}

Related

Sitecore - get all indexed items

I am using lucene search to get bucket items filtered by some string and this is my code:
var innerQuery = new FullTextQuery(myString);
var hits = searchContext.Search(innerQuery, searchIndex.GetDocumentCount());
Is there some query or something different that will let me get all indexed items? I tried with empty "myString" but there is an error that it cannot be empty.
You can use Lucene.Net.Search.MatchAllDocsQuery:
SearchHits hits = searchContext.Search(new MatchAllDocsQuery(), int.MaxValue);

CDbMigration::update does not work inside foreach loop

Following this question. There is something wrong, when using CDbMigration::update() inside foreach loop.
This code does not work correctly:
//This is executed inside Yii migration, so $this is CDbMigration.
foreach($idMap as $menuId=>$pageId)
{
$this->update
(
'menus_items',
array('link'=>'/content/show?id='.$pageId),
array('id = '.$menuId)
);
}
For each item in $idMap value of $pageId is always the same and equals value of last item in $idMap array. Therefore, every menu item points to the same URL.
This code works like a charm:
foreach($idMap as $menuId=>$pageId)
{
$sql = "UPDATE `menus_items` SET link = '/content/show?id=".$pageId."' WHERE id = ".$menuId."; ";
Yii::app()->db->createCommand($sql)->execute();
}
For each item in $idMap value of $pageId is always different and equals value of current item in $idMap array. Therefore, every menu item points to correct URL.
The same goes, when executing all statements in one SQL query:
$sql = '';
foreach($idMap as $menuId=>$pageId)
{
$sql .= "UPDATE `menus_items` SET link = '/content/show?id=".$pageId."' WHERE id = ".$menuId."; ";
}
Yii::app()->db->createCommand($sql)->execute();
Again, everything is OK.
Why using CDbMigration::update() fails, while direct SQL execution works like a charm?
I don't think you are providing the criteria parameter properly # array('id = '.$menuId)
. You should use a string if you want to send it like that, putting it in an array presumes you are mapping out the conditions in a key => value pair. Also you should be wrapping the value constraint in quotes id = "$menuId".

Ordering a query by the string length of one of the fields

In RavenDB (build 2330) I'm trying to order my results by the string length of one of the indexed terms.
var result = session.Query<Entity, IndexDefinition>()
.Where(condition)
.OrderBy(x => x.Token.Length);
However the results look to be un-sorted. Is this possible in RavenDB (or via a Lucene query) and if so what is the syntax?
You need to add a field to IndexDefinition to order by, and define the SortOption to Int or something more appropriate (however you don't want to use String which is default).
If you want to use the Linq API like in your example you need to add a field named Token_Length to the index' Map function (see Matt's comment):
from doc in docs
select new
{
...
Token_Length = doc.TokenLength
}
And then you can query using the Linq API:
var result = session.Query<Entity, IndexDefinition>()
.Where(condition)
.OrderBy(x => x.Token.Length);
Or if you really want the field to be called TokenLength (or something other than Token_Length) you can use a LuceneQuery:
from doc in docs
select new
{
...
TokenLength = doc.Token.Length
}
And you'd query like this:
var result = session.Advanced.LuceneQuery<Entity, IndexDefinition>()
.Where(condition)
.OrderBy("TokenLength");

How do I get a list of fields in a generic sObject?

I'm trying to build a query builder, where the sObject result can contain an indeterminate number of fields. I'm using the result to build a dynamic table, but I can't figure out a way to read the sObject for a list of fields that were in the query.
I know how to get a list of ALL fields using the getDescribe information, but the query might not contain all of those fields.
Is there a way to do this?
Presumably you're building the query up as a string, since it's dynamic, so couldn't you just loop through the fields in the describe information, and then use .contains() on the query string to see if it was requested? Not crazy elegant, but seems like the simplest solution here.
Taking this further, maybe you have the list of fields selected in a list of strings or similar, and you could just use that list?
Not sure if this is exactly what you were after but something like this?
public list<sObject> Querylist {get; set;}
Define Search String
string QueryString = 'select field1__c, field2__c from Object where';
Add as many of these as you need to build the search if the user searches on these fields
if(searchParameter.field1__c != null && searchParameter.field1__c != '')
{
QueryString += ' field1__c like \'' + searchParameter.field1__c + '%\' and ';
}
if(searchParameter.field2__c != null && searchParameter.field2__c != '')
{
QueryString += ' field2__c like \'' + searchParameter.field2__c + '%\' and ';
}
Remove the last and
QueryString = QueryString.substring(0, (QueryString.length()-4));
QueryString += ' limit 200';
add query to the list
for(Object sObject : database.query(QueryString))
{
Querylist.add(sObject);
}
To get the list of fields in an sObject, you could use a method such as:
public Set<String> getFields(sObject sobj) {
Set<String> fieldSet = new Set<String>();
for (String field : sobj.getSobjectType().getDescribe().fields.getMap().keySet()) {
try {
a.get(field);
fieldSet.add(field);
} catch (Exception e) {
}
}
return fieldSet;
}
You should refactor to bulkily this approach for your context, but it works. Just pass in an sObject and it'll give you back a set of the field names.
I suggest using a list of fields for creating both the query and the table. You can put the list of fields in the result so that it's accesible for anyone using it. Then you can construct the table by using result.getFields() and retrieve the data by using result.getRows().
for (sObject obj : result.getRows()) {
for (String fieldName : result.getFields()) {
table.addCell(obj.get(fieldName));
}
}
If your trying to work with a query that's out of your control, you would have to parse the query to get the list of fields. But I wouldn't suggest trying that. It complicates code in ways that are hard to follow.

SharePoint 2010 "foreach"

I have 2 SharePoint lists, and I have to copy all items from List1 to List2.
On List1 there is a boolean field (defaults to 'no'), a text field and an associated WorkFlow which triggers on modifications.
The WokFlow simplified:
Copy current item to List2
Set my boolen field to 'yes'
Search for an item with boolen field 'no', set its text field to 'copy'
I start the process by modifing an item in List1, then it will copy itself to List2, modifies an another item, and so on... until there is any item with a boolen field set to 'no'.
This works perfectly for 10 items, but then it fails. Item 10 modified item 11's text field to 'copy', but item 11's WorkFlow does not started. I've tried it serval times, and always stopped after 10 copies.
I've Googled and MSDN'd. The best solution I've found is to pause for 1 minute in the WorkFlow. But I have thousands of items...
Has anyone any advice? I even cant find any limit in the SharePoint 2010 server that defaults to 10.
Thank You!
You are triggering a hardcoded resource throttle in SharePoint 2010 due to the speed on the workflow. It's there to prevent the system from becoming unresponsive during workflow operations. Code in an application page or timer job will get around this limit but it's not recommended to have a greedy operation that cause the system to become unresponsive to users.
You can do CAML batch methods.
somethig like this:
void UpdateList()
{
StringBuilder methodBuilder = new StringBuilder();
string batch = string.Empty;
string newValue="mmmm";
string updateColumn = "SampleColumn";
try
{
string batchFormat = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<ows:Batch OnError=\"Continue\">{0}</ows:Batch>";
string methodFormat = "<Method ID='{0}' >" +
"<SetList>{1}</SetList>" +
"<SetVar Name='Cmd'>Save</SetVar>" +
"<SetVar Name='ID'>{2}</SetVar>" +
"<SetVar Name='urn:schemas-microsoft-com:office:office#{3}'>{4}</SetVar>" +
"</Method>";
using (SPSite siteCol = new SPSite("SampleSite"))
{
using (SPWeb web = siteCol.OpenWeb())
{
// Get the list containing the items to update
SPList list = web.Lists["SampleList"];
string listGuid = list.ID.ToString();
SPListItemCollection allItems = list.GetItems();
// Build the CAML update commands.
for (int i = 0; i < allItems.Count; i++)
{
int itemID = allItems[i].ID;
methodBuilder.AppendFormat(methodFormat, itemID, listGuid, itemID, updatedColumn, newValue);
}
web.AllowUnsafeUpdates = true;
// Generate the CAML
batch = string.Format(batchFormat, methodBuilder.ToString());
// Process the batch
string batchReturn = web.ProcessBatchData(batch);
}
//done
}
}
catch (Exception ex)
{
//show the error
}
}
You can create batch methods for create , delete and update items on lists and document libraries.
Refs:
http://msdn.microsoft.com/en-us/library/office/ms437562%28v=office.15%29.aspx
http://msdn.microsoft.com/en-us/library/office/ms459050(v=office.15).aspx
if you want to change workflow concurrent execution limits ....
For check limits:
Get-SPFarmConfig | Select WorkflowPostponeThreshold
For change
Set-SPFarmConfig -WorkflowPostponeThreshold 50
Timer service process items ( workflows continuations) on batch sizes
Get-SPFarmConfig | Select WorkflowBatchSize
Set-SPFarmConfig -WorkflowBatchSize 150