Monday, March 11, 2013

Creating a Generic List of Anonymous Types using Casting by Example

Consider the following scenario. You have two lists of data which are the result of separate queries. The select in the queries is identical and you want to merge the lists into a generic anonymous list to display the results in a control.

The code below receives a pipe delimited string, the string contains keywords. The code loops the string array and executes two separate queries against separate fields (coded this way for the purpose of this example) the biggest obstacle would be how to combine the results of the queries into a single list.

In order to merge the lists into one, it is possible to use a technique called Casting by Example, by creating an anonymous type that matches the intended select, it will be possible to cast this type into an array and then into a list. See below:

var result = new {Id = 1, CriteriaId = 0, MarketName = string.Empty};
var results = (new[] {result}).ToList();
Here is the complete code for your review:
var keywords = p.Split('|');
if (keywords.Length == 0)
    return;
           
var result = new {Id = 1, CriteriaId = 0, MarketName = string.Empty};
var results = (new[] {result}).ToList();
                
using (var ctxt = new MarketSearchDataContext())
{                
  foreach (var keyword in keywords)
  {
   var nameResults = ctxt.Markets.Where(m => m.MarketName.ToLower()
       .Contains(keyword.ToLower().Trim()))
       .Select(m => new {Id = m.Id, CriteriaId = 0, MarketName = m.MarketName})
       .ToList();

   var detailResults = ctxt.Markets.Where(m => m.HTML
       .Contains(keyword.ToLower().Trim()))
       .Select(m => new { Id = m.Id, CriteriaId = 0, MarketName = m.MarketName })
       .ToList();
   if (nameResults.Count > 0)
       results.AddRange(nameResults);

   if (detailResults.Count > 0)
        results.AddRange(detailResults);
}

//Raw results from the list - Duplicates will exist
results.RemoveAt(0); //Cast by Example row
var cleanResults = results.Distinct();

BindResultsGrid(cleanResults);

1 comment:

  1. Nice post. I was checking continuously this weblog and I'm impressed! Extremely useful information specially the last section :) I handle such information much. I used to be looking for this certain info for a very long time. Thank you and good luck.

    Here is my blog post adventure tours thailand

    ReplyDelete