String[] in columns returned from KeywordQuery.Execute

Posted Thursday, December 11, 2008 10:17 AM by CoreyRoth

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)
(required)
(optional)
(required)