in

Dot Net Mafia

Group site for developer blogs dealing with (usually) .NET, SharePoint 2013, SharePoint 2010, Office 365, SharePoint Online, and other Microsoft products, as well as some discussion of general programming related concepts.

This Blog

Syndication

Archives

Corey Roth [MVP]

A SharePoint MVP bringing you the latest time saving tips for SharePoint 2013, Office 365 / SharePoint Online and Visual Studio 2013.

String[] in columns returned from KeywordQuery.Execute

I have posted in the past about how to use the KeywordQuery class to execute an Enterprise Search query.  This makes it easy to get a DataTable containing search results.  However, one caveat with this is that some columns get returned as a string array (string[]) instead of a string.  This can make data binding a pain.  If you wanted to bind your DataTable to a GridView, it simply will not display these columns.  I used to think it had something to do with it only happening on custom managed properties that you create, but that is not actually the cast.  It turns out this is actually related to the post yesterday, because it seems to happen for the same reason.  If you have a managed property that has more than one crawled property mapped to it, you get a string[] instead of a string.  I am sure there is a good reason for this, but I don't know what it is.

So how do we deal with this?  Option 1 of course is to only map one crawled property to your managed properties.  This is probably not going to be an ideal solution.  Another option we have is to use LINQ to DataSets to coerce that string[] into something usable.  First, we execute the query and load into a DataTable as usual. 

// execute the query and put it in a dataTable

ResultTableCollection queryResults = keywordQuery.Execute();

ResultTable queryResultsTable = queryResults[ResultType.RelevantResults];

DataTable queryDataTable = new DataTable();

queryDataTable.Load(queryResultsTable, LoadOption.OverwriteChanges);

In this case, I want to bind the builtin Title managed property as well as two of my own managed properties.  I use LINQ to DataSets to put these into a new anonymous type.  The Field property is generic so you can specify the type that you want.  In this case string[].  Notice the Title property doesn't require the use of the string array.

var formattedResults = from row in queryDataTable.AsEnumerable()

                       select new

                       {

                           Title = row.Field<string>("Title"),

                           MyManagedProperty1 = row.Field<string[]>("MyManagedProperty1")[0],

                           MyManagedProperty2 = row.Field<string[]>("MyManagedProperty2")[0]

                       };

We then can bind this to a GridView as usual (if that's what you need it for).

SearchGridView.DataSource = formattedResults;

SearchGridView.DataBind();

I am sure there is a good reason that these fields get returned as a string[].  If you don't like these options, you can always call the web service and get the results as XML.

Comments

No Comments

Leave a Comment

(required)  
(optional)
(required)  
Add

About CoreyRoth

Corey Roth is an Applications Architect at Infusion specializing in ECM and Search.
2012 dotnetmafia.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems