<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Solutionizing .NET &#187; Hacking LINQ</title>
	<atom:link href="http://solutionizing.net/tag/hacking-linq/feed/" rel="self" type="application/rss+xml" />
	<link>http://solutionizing.net</link>
	<description>Random thoughts on custom development in SharePoint.</description>
	<lastBuildDate>Fri, 03 Feb 2012 05:41:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='solutionizing.net' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Solutionizing .NET &#187; Hacking LINQ</title>
		<link>http://solutionizing.net</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://solutionizing.net/osd.xml" title="Solutionizing .NET" />
	<atom:link rel='hub' href='http://solutionizing.net/?pushpress=hub'/>
		<item>
		<title>Hacking LINQ Expressions: Join With Comparer</title>
		<link>http://solutionizing.net/2009/09/19/hacking-linq-expressions-join-with-comparer/</link>
		<comments>http://solutionizing.net/2009/09/19/hacking-linq-expressions-join-with-comparer/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 18:13:27 +0000</pubDate>
		<dc:creator>Keith Dahlby</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[Hacking LINQ]]></category>
		<category><![CDATA[IEqualityComparer]]></category>
		<category><![CDATA[LINQ Join]]></category>

		<guid isPermaLink="false">http://solutionizing.net/?p=681</guid>
		<description><![CDATA[In this installment of my Hacking LINQ series we&#8217;ll take a look at providing an IEqualityComparer for use in a LINQ join clause. The Problem Many of the Standard Query Operators require comparing sequence elements and the default query providers are kind enough to give us overloads that accept a suitable comparer. Among these operators, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=solutionizing.net&amp;blog=3982353&amp;post=681&amp;subd=solutionizing&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In this installment of my <a href="http://solutionizing.net/tag/hacking-linq/">Hacking LINQ</a> series we&#8217;ll take a look at providing an <code>IEqualityComparer</code> for use in a LINQ <code>join</code> clause.</p>
<h2>The Problem</h2>
<p>Many of the <a title="Standard Query Operators Overview" href="http://msdn.microsoft.com/en-us/library/bb397896.aspx">Standard Query Operators</a> require comparing sequence elements and the default query providers are kind enough to give us overloads that accept a suitable comparer. Among these operators, <code>Join</code> and <code>GroupJoin</code> have perhaps the most useful query syntax:</p>
<pre> var res = from s in States
          join a in AreaCodes
            on s.Abbr equals a.StateAbbr
          select new { s.Name, a.AreaCode };</pre>
<p>While a bit more verbose, I find the intent much easier to read then the method equivalent:</p>
<pre>var res = States.Join(AreaCodes,
                      s =&gt; s.Abbr, a =&gt; a.StateAbbr,
                      (s, a) =&gt; new { s.Name, a.AreaCode });</pre>
<p>Or maybe I&#8217;ve just spent too much time in SQL. Either way, I thought it would be useful to support joins by a comparer.</p>
<h2>The Goal</h2>
<p>We will use another extension method to specify how the join should be performed:</p>
<pre>var res = from s in States
          join a in AreaCodes.WithComparer(StringComparer.OrdinalIgnoreCase)
            on s.Abbr equals a.StateAbbr
          select new { s.Name, a.AreaCode };</pre>
<p>We can also support the same syntax for group joins:</p>
<pre>var res = from s in States
          join a in AreaCodes.WithComparer(StringComparer.OrdinalIgnoreCase)
            on s.Abbr equals a.StateAbbr into j
          select new { s.Name, Count = j.Count() };</pre>
<h2>The Hack</h2>
<p>As with most LINQ hacks, we&#8217;re going to use the result of <code>WithComparer</code> to call a specialized version of <code>Join</code> or <code>GroupJoin</code>, in this case by providing a replacement for the join&#8217;s inner sequence:</p>
<pre>var res = States.Join(AreaCodes.WithComparer(StringComparer.OrdinalIgnoreCase),
                      s =&gt; s.Abbr, a =&gt; a.StateAbbr,
                      (s, a) =&gt; new { s.Name, a.AreaCode });</pre>
<p>Eventually leading to this method call:</p>
<pre>var res = States.Join(AreaCodes,
                      s =&gt; s.Abbr, a =&gt; a.StateAbbr,
                      (s, a) =&gt; new { s.Name, a.AreaCode },
                      StringComparer.OrdinalIgnoreCase);</pre>
<p>Since we need both the inner collection we&#8217;re extending and the comparer, we can guess our extension method will be implemented something like this:</p>
<pre>public static JoinComparerProvider&lt;T, TKey&gt; WithComparer&lt;T, TKey&gt;(
    this IEnumerable&lt;T&gt; inner, IEqualityComparer&lt;TKey&gt; comparer)
{
    return new JoinComparerProvider&lt;T, TKey&gt;(inner, comparer);
}</pre>
<p>With a trivial provider implementation:</p>
<pre>public sealed class JoinComparerProvider&lt;T, TKey&gt;
{
    internal JoinComparerProvider(IEnumerable&lt;T&gt; inner, IEqualityComparer&lt;TKey&gt; comparer)
    {
        Inner = inner;
        Comparer = comparer;
    }

    public IEqualityComparer&lt;TKey&gt; Comparer { get; private set; }
    public IEnumerable&lt;T&gt; Inner { get; private set; }
}</pre>
<p>The final piece is our <code>Join</code> overload:</p>
<pre>public static IEnumerable&lt;TResult&gt; Join&lt;TOuter, TInner, TKey, TResult&gt;(
    this IEnumerable&lt;TOuter&gt; outer,
    JoinComparerProvider&lt;TInner, TKey&gt; inner,
    Func&lt;TOuter, TKey&gt; outerKeySelector,
    Func&lt;TInner, TKey&gt; innerKeySelector,
    Func&lt;TOuter, TInner, TResult&gt; resultSelector)
{
    return outer.Join(inner.Inner, outerKeySelector, innerKeySelector,
                      resultSelector, inner.Comparer);
}</pre>
<p>Implementations of <code>GroupJoin</code> and their <code>IQueryable</code> counterparts are similarly trivial.</p>
<br /> Tagged: Hacking LINQ, IEqualityComparer, LINQ Join <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/solutionizing.wordpress.com/681/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/solutionizing.wordpress.com/681/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/solutionizing.wordpress.com/681/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/solutionizing.wordpress.com/681/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/solutionizing.wordpress.com/681/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/solutionizing.wordpress.com/681/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/solutionizing.wordpress.com/681/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/solutionizing.wordpress.com/681/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/solutionizing.wordpress.com/681/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/solutionizing.wordpress.com/681/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/solutionizing.wordpress.com/681/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/solutionizing.wordpress.com/681/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/solutionizing.wordpress.com/681/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/solutionizing.wordpress.com/681/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=solutionizing.net&amp;blog=3982353&amp;post=681&amp;subd=solutionizing&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://solutionizing.net/2009/09/19/hacking-linq-expressions-join-with-comparer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/26483382e3717e58e4c45d06c8ec351d?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">dahlbyk</media:title>
		</media:content>
	</item>
		<item>
		<title>Hacking LINQ Expressions: Select With Index</title>
		<link>http://solutionizing.net/2009/09/15/hacking-linq-expressions-select-with-index/</link>
		<comments>http://solutionizing.net/2009/09/15/hacking-linq-expressions-select-with-index/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 09:04:12 +0000</pubDate>
		<dc:creator>Keith Dahlby</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[Hacking LINQ]]></category>

		<guid isPermaLink="false">http://solutionizing.net/?p=671</guid>
		<description><![CDATA[First, a point of clarification: I use LINQ Expressions to mean (Language-INtegrated) Query Expressions (the language feature) rather than Expression Trees (the .NET 3.5 library in System.Linq.Expressions). So what do I mean by &#8220;Hacking LINQ Expressions&#8221;? Quite simply, I&#8217;m not content with the rather limited set of operations that query expressions allow me to represent. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=solutionizing.net&amp;blog=3982353&amp;post=671&amp;subd=solutionizing&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>First, a point of clarification: I use LINQ Expressions to mean (Language-INtegrated) Query Expressions (the language feature) rather than Expression Trees (the .NET 3.5 library in System.Linq.Expressions).</p>
<p>So what do I mean by &#8220;Hacking LINQ Expressions&#8221;? Quite simply, I&#8217;m not content with the rather limited set of operations that query expressions allow me to represent. By understanding how queries are translated, we can use various techniques to broaden our expressive reach. I have already documented one such hack for <a title="Using IDisposables with LINQ" href="http://solutionizing.net/2009/07/23/using-idisposables-with-linq/">managing IDisposable objects with LINQ</a>, so I guess we can call this the second in an unbounded series.</p>
<h2>The Problem</h2>
<p>In thinking over use cases for <a title="Functional Construction for ASP.NET Web Forms" href="http://solutionizing.net/2009/09/13/functional-construction-for-asp-net-web-forms/">functional construction of web control trees</a>, I paused to think through how I would express alternate row styling. My mind immediately jumped to the <a title="Enumerable.Select&lt;TSource, TResult&gt; Method (IEnumerable&lt;TSource&gt;, Func&lt;TSource, Int32, TResult&gt;)" href="http://msdn.microsoft.com/en-us/library/bb534869.aspx">overload of Select()</a> that exposes the current element&#8217;s index:</p>
<pre>Controls.Add(
    new Table().WithControls(
        data.Select((x, i) =&gt;
            new TableRow() {
                CssClass = i % 2 == 0 ? "" : "alt"
            }.WithControls(
                new TableCell().WithControls(x)
            )
        )
    )
);</pre>
<p>This works fine for simple cases, but breaks down for more complex queries:</p>
<pre>Controls.Add(
    new Table().WithControls((
        from x in Xs
        join y in Ys on x.Key equals y.Key
        select new { x, y }
        ).Select((z, i) =&gt;
            new TableRow() {
                CssClass = i % 2 == 0 ? "" : "alt"
            }.WithControls(
                new TableCell().WithControls(z.x.ValueX, z.y.ValueY)
            )
        )
    )
);</pre>
<h2>The Goal</h2>
<p>Instead, I propose a simple extension method to retrieve an index at arbitrary points in a query:</p>
<pre>var res = from x in data
          from i in x.GetIndex()
          select new { x, i };</pre>
<p>Or our control examples:</p>
<pre>Controls.Add(
    new Table().WithControls(
        from x in data
        from i in x.GetIndex()
        select new TableRow() {
            CssClass = i % 2 == 0 ? "" : "alt"
        }.WithControls(
            new TableCell().WithControls(x)
        )
    )
);

Controls.Add(
    new Table().WithControls(
        from x in Xs
        join y in Ys on x.Key equals y.Key
        from i in y.GetIndex()
        select new TableRow() {
            CssClass = i % 2 == 0 ? "" : "alt"
        }.WithControls(
            new TableCell().WithControls(x.ValueX, y.ValueY)
        )
    )
);</pre>
<p>Much like in the <code>IDisposable</code> solution, we use a <code>from</code> clause to act as an intermediate assignment. But in this case our hack is a bit trickier than a simple iterator.</p>
<h2>The Hack</h2>
<p>For this solution we&#8217;re going to take advantage of how multiple <code>from</code> clauses are translated:</p>
<pre>var res = data.SelectMany(x =&gt; x.GetIndex(), (x, i) =&gt; new { x, i });</pre>
<p>Looking at the parameter list, we see that our <code>collectionSelector</code> should return the result of <code>x.GetIndex()</code> and our <code>resultSelector</code>&#8216;s second argument needs to be an <code>int</code>:</p>
<pre>public static IEnumerable&lt;TResult&gt; SelectMany&lt;TSource, TResult&gt;(
    this IEnumerable&lt;TSource&gt; source,
    Func&lt;TSource, SelectIndexProvider&gt; collectionSelector,
    Func&lt;TSource, int, TResult&gt; resultSelector)</pre>
<p>The astute observer will notice that the signature of this <code>resultSelector</code> exactly matches the <code>selector</code> used by <code>Select</code>&#8216;s with-index overload, trivializing the method implementation:</p>
<pre>{
    return source.Select(resultSelector);
}</pre>
<p>Note that we&#8217;re not even using <code>collectionSelector</code>! We&#8217;re just using its return type as a flag to force the compiler to use this version of <code>SelectMany()</code>. The rest of the pieces are incredibly simple now that we know the actual <code>SelectIndexProvider</code> value is never used:</p>
<pre>public sealed class SelectIndexProvider
{
    private SelectIndexProvider() { }
}

public static SelectIndexProvider GetIndex&lt;T&gt;(this T element)
{
    return null;
}</pre>
<p>And for good measure, an equivalent version to extend IQueryable&lt;&gt;:</p>
<pre>public static IQueryable&lt;TResult&gt; SelectMany&lt;TSource, TResult&gt;(
    this IQueryable&lt;TSource&gt; source,
    Expression&lt;Func&lt;TSource, SelectIndexProvider&gt;&gt; collectionSelector,
    Expression&lt;Func&lt;TSource, int, TResult&gt;&gt; resultSelector)
{
    return source.Select(resultSelector);
}</pre>
<p>Because we&#8217;re just calling <code>Select()</code>, the query expression isn&#8217;t even aware of the call to <code>GetIndex()</code>:</p>
<blockquote><p>System.Linq.Enumerable+&lt;RangeIterator&gt;d__b1.Select((x, i) =&gt; (x * i))</p></blockquote>
<p>We&#8217;re essentially providing our own syntactic sugar over the sugar already provided by query expressions. Pretty sweet, eh?</p>
<p>As a final exercise for the reader, what would this print?</p>
<pre>var res = from x in Enumerable.Range(1, 5)
          from i in x.GetIndex()
          from y in Enumerable.Repeat(i, x)
          where y % 2 == 1
          from j in 0.GetIndex()
          select i+j;

foreach (var r in res)
    Console.WriteLine(r);</pre>
<br /> Tagged: Hacking LINQ <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/solutionizing.wordpress.com/671/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/solutionizing.wordpress.com/671/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/solutionizing.wordpress.com/671/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/solutionizing.wordpress.com/671/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/solutionizing.wordpress.com/671/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/solutionizing.wordpress.com/671/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/solutionizing.wordpress.com/671/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/solutionizing.wordpress.com/671/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/solutionizing.wordpress.com/671/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/solutionizing.wordpress.com/671/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/solutionizing.wordpress.com/671/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/solutionizing.wordpress.com/671/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/solutionizing.wordpress.com/671/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/solutionizing.wordpress.com/671/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=solutionizing.net&amp;blog=3982353&amp;post=671&amp;subd=solutionizing&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://solutionizing.net/2009/09/15/hacking-linq-expressions-select-with-index/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/26483382e3717e58e4c45d06c8ec351d?s=96&#38;d=identicon&#38;r=PG" medium="image">
			<media:title type="html">dahlbyk</media:title>
		</media:content>
	</item>
	</channel>
</rss>
