<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog For .NET &#187; linq to sql</title>
	<atom:link href="http://www.blogfor.net/tag/linq-to-sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.blogfor.net</link>
	<description>welcome to the blogosphere</description>
	<lastBuildDate>Sun, 02 May 2010 17:20:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Dynamic Sorting and Filtering with Linq To SQL</title>
		<link>http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=dynamic-sorting-and-filtering-with-linq-to-sql</link>
		<comments>http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 02:23:18 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[linq to sql]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=140</guid>
		<description><![CDATA[Dynamic sorting in Linq to Sql using lambda expressions and column names]]></description>
			<content:encoded><![CDATA[<p>A common paradigm in my current work involves separating sort logic from the data access layer that applies it. The end user may sort a table/view by any number of criteria and in fairly complex ways.</p>
<p>One simple way to achieve this is through a switch statement:</p>
<pre name="code" class="c#">private IOrderedQueryable&lt;Customer&gt; SortData(String sortExpression, IQueryable&lt;Customer&gt; query)
  {
   sortExpression = sortExpression ?? "CompanyName";
   IOrderedQueryable&lt;Customer&gt; orderedQuery = null;
   switch (sortExpression)
   {
    case "CompanyName":
     orderedQuery = query.OrderBy(x =&gt; x.CompanyName);
     break;
    case "Count":
     orderedQuery = query.OrderBy(x =&gt; x.Orders.Count());
     break;
    default:
     orderedQuery = query.OrderBy(x =&gt; x);
     break;
   }
   return orderedQuery;
  }</pre>
<p>This quickly breaks down because we would need to include a case for every possible sort expression. There&#8217;s a fairly common approach at <a href="http://weblogs.asp.net/davidfowler/archive/2008/12/11/dynamic-sorting-with-linq.aspx">http://weblogs.asp.net/davidfowler/archive/2008/12/11/dynamic-sorting-with-linq.aspx</a> to dynamically sort on a table&#8217;s columns. This works well but the approach does not lend itself to more complicated expressions e.g. sort customers by their number of orders.</p>
<p>We sought to create a framework for developers to filter and sort listings by any combination of criteria. As long as Linq to Sql supported the lamda expression, the developer should be free to populate a custom &#8220;filter&#8221; object with a list of &#8220;where&#8221; and &#8220;order by&#8221; information needed to act upon the table or view.</p>
<p>When filtering a sequence, Linq to Sql has no trouble converting lamda expressions that return booleans into t-sql &#8220;where&#8221; clauses &#8211; the boolean return value matches the necessary return value of the sql expression generated. The filter expression then can simply be:</p>
<pre name="code" class="c#">
Expression&lt;Func&lt;T, Boolean&gt;&gt; filterExpression
</pre>
<p>When sorting a sequence, however, the lamdba expression must return a Type that supports IComparable. A simplistic approach to dynamic sorting would then be to use sort expressions of the form:</p>
<pre name="code" class="c#">Expression&lt;Func&lt;T, IComparable&gt;&gt; sortExpression</pre>
<p>and apply them as</p>
<pre name="code" class="c#">sortedQry = qry.OrderBy(sortExpression);</pre>
<p>This will work just fine when querying objects, but will fail when used with Linq to Sql. Depending on the return type, the runtime may force a cast to IComparable &#8211; something Linq to Sql doesn&#8217;t know how to do.</p>
<p><a rel="attachment wp-att-141" href="http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/icompareableerror/"><img class="alignnone size-medium wp-image-141" title="icompareableerror" src="http://www.blogfor.net/wp-content/uploads/2009/09/icompareableerror.png" alt="icompareableerror" width="601" height="263" /></a></p>
<p>The error specifically ocurrs when the return value of the expression is a DateTime, Int32, etc. </p>
<p>To work around this we need to avoid casting the return value of the lamdba expression and instead let Linq to Sql know explicitly what type the expression returns.</p>
<p><a rel="attachment wp-att-143" href="http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/templatedlamdbal2sqltooltip-noicompare/"><img class="alignnone size-full wp-image-143" title="templatedlamdbal2sqltooltip-noicompare" src="http://www.blogfor.net/wp-content/uploads/2009/09/templatedlamdbal2sqltooltip-noicompare.jpg" alt="templatedlamdbal2sqltooltip-noicompare" width="515" height="37" /></a></p>
<p>instead of this:</p>
<p><a rel="attachment wp-att-144" href="http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/icompareablel2sqltooltip-icomparablecast/"><img class="alignnone size-full wp-image-144" title="icompareablel2sqltooltip-icomparablecast" src="http://www.blogfor.net/wp-content/uploads/2009/09/icompareablel2sqltooltip-icomparablecast.jpg" alt="icompareablel2sqltooltip-icomparablecast" width="570" height="40" /></a></p>
<p>We could, for instance, create a variable for each return type:</p>
<pre name="code" class="c#">
Expression&lt;Func&lt;T, DateTime&gt;&gt; sortExpressionDate

Expression&lt;Func&lt;T, Int32&gt;&gt; sortExpressionInt32

...</pre>
<p>Such a framework is too cumbersome to use effectively. Instead, we can avoid the cast by telling .net at compile time the return type of the lamda expression.</p>
<pre name="code" class="c#">Expression&lt;Func&lt;T, TKey&gt;&gt; SortExpression</pre>
<p> for example:</p>
<pre name="code" class="c#">Expression&lt;Func&lt;Customer, Int32&gt;&gt; sortExpression = x =&gt; x.Orders.Count();</pre>
<p>In my specific case, I used a filter to encapsulate the logic needed to filter and sort a sequence.</p>
<pre name="code" class="c#">public class Filter&lt;T&gt;
 {
  /// &lt;summary&gt;
  /// the list of filters applied to the sequence. The filters will act as a series of "and" clauses against the data source.
  /// &lt;/summary&gt;
  public List&lt;Expression&lt;Func&lt;T, Boolean&gt;&gt;&gt; Filters...

   /// &lt;summary&gt;
  /// the list of sorts to apply to the resulting sequence of items.
  /// &lt;/summary&gt;
  public List&lt;ISortOrder&lt;T&gt;&gt; SortCriteria...
  }

public interface ISortOrder&lt;T&gt;
 {
  SortDirection Direction { get; set; }
  IOrderedQueryable&lt;T&gt; ApplyOrdering(IQueryable&lt;T&gt; query, Boolean useThenBy);
 }</pre>
<p>For example, the following code filters by companyName and a minimum number of orders; then sorts by the column name specified by the &#8220;propertyNameToSortBy&#8221; variable followed by the count of orders:</p>
<pre name="code" class="c#">var filter = new Filter&lt;Customer&gt;();

filter.Filters.Add(x =&gt; x.CompanyName.Contains(searchText));

filter.Filters.Add(x =&gt; x.Orders.Count &lt; numberOfOrders);

filter.SortCriteria.Add(new FieldSortOrder&lt;Customer&gt;(propertyNameToSortBy));

var sortBy = new ExpressionSortOrder&lt;Customer, Int32&gt;()
     {
      SortExpression = x =&gt; x.Orders.Count,
      Direction = (sortExpression.ToLowerInvariant().EndsWith("desc")) ? DynamicSorter.SortDirection.Descending : DynamicSorter.SortDirection.Ascending
     };
     filter.SortCriteria.Add(sortBy);

return FilterItems(filter);</pre>
<p> the code for the FilterItems method then is relatively simple:</p>
<pre name="code" class="c#">public static IEnumerable&lt;Customer&gt; FilterItems(Filter&lt;Customer&gt; filter)
  {
   var dc = new NorthwindDataContext();

   IQueryable&lt;Customer&gt; sequence = dc.Customers;
   foreach (var filterClause in filter.Filters)
   {
    sequence = sequence.Where(filterClause);
   }
   if (filter.SortCriteria.Count &gt; 0)
   {
    var sortCriteria = filter.SortCriteria[0];
    var orderedSequence = sortCriteria.ApplyOrdering(sequence, false);
    if (filter.SortCriteria.Count &gt; 1)
    {
     for (var i = 1; i &lt; filter.SortCriteria.Count; i++)
     {
      sortCriteria = filter.SortCriteria[i];
      orderedSequence = sortCriteria.ApplyOrdering(sequence, false);
     }
    }
    sequence = orderedSequence;
   }
   return sequence;
  }</pre>
<p>In the end, we used T4 templates to codegen entity specific filter objects and static methods to filter tables and views &#8211; more about that in my next post.</p>
<p>A sample northwind based sample can be found <a href="http://www.blogfor.net/wp-content/uploads/2009/09/dynamicsorter.zip">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
