title: LINQ Join on a Nullable key
body: <p>The LINQ <code>Join()</code> method with <code>Nullable&lt;int&gt;</code> for <code>TKey</code> skips over null key matches.  What am I missing in the documentation?  I know that I can switch to <code>SelectMany()</code>, I'm just curious why this equality operation works like SQL and not like C# since as near as I can tell, the <code>EqualityComparer&lt;int?&gt;.Default</code> works exactly like I would expect it to for null values.</p>
  
  <p><a href="http://msdn.microsoft.com/en-us/library/bb534675.aspx">http://msdn.microsoft.com/en-us/library/bb534675.aspx</a></p>
  
  <pre><code>using System;
  using System.IO;
  using System.Linq;
  using System.Collections.Generic;
  
  public class dt
  {
     public int? Id;
     public string Data;
  }
  
  public class JoinTest
  {
      public static int Main(string [] args)
      {
          var a = new List&lt;dt&gt;
          {
              new dt { Id = null, Data = "null" },
              new dt { Id = 1, Data = "1" },
              new dt { Id = 2, Data = "2" }
          };
  
          var b = new List&lt;dt&gt;
          {
              new dt { Id = null, Data = "NULL" },
              new dt { Id = 2, Data = "two" },
              new dt { Id = 3, Data = "three" }
          };
  
          //Join with null elements
          var c = a.Join( b,
              dtA =&gt; dtA.Id,
              dtB =&gt; dtB.Id,
              (dtA, dtB) =&gt; new { aData = dtA.Data, bData = dtB.Data } ).ToList();
          // Output:
          // 2 two
          foreach ( var aC in c )
              Console.WriteLine( aC.aData + " " + aC.bData );
          Console.WriteLine( " " );
  
          //Join with null elements converted to zero
          c = a.Join( b,
              dtA =&gt; dtA.Id.GetValueOrDefault(),
              dtB =&gt; dtB.Id.GetValueOrDefault(),
              (dtA, dtB) =&gt; new { aData = dtA.Data, bData = dtB.Data } ).ToList();
  
          // Output:
          // null NULL
          // 2 two
          foreach ( var aC in c )
              Console.WriteLine( aC.aData + " " + aC.bData );
  
          Console.WriteLine( EqualityComparer&lt;int?&gt;.Default.Equals( a[0].Id, b[0].Id ) );
          Console.WriteLine( EqualityComparer&lt;object&gt;.Default.Equals( a[0].Id, b[0].Id ) );
          Console.WriteLine( a[0].Id.Equals( b[0].Id ) );
  
          return 0;
      }
  }
  </code></pre>