title: Interesting Linq to SQL common base class behavior
body: <p>It's a question about <strong>InvalidOperationException</strong> with message <em>Class member X is unmapped.</em></p>
  
  <p>One of our system has  the same <strong>base entity</strong> for each LinqToSql entity with framework version 3.5.</p>
  
  <p>I ran into a very strange problem and I started a research about it. I made a very small project to be able to localize the problem more easily.</p>
  
  <p><strong>Entity base class</strong></p>
  
  <pre><code>public abstract class EntityBase
  {
      public virtual long ID { get; set; }
  }
  </code></pre>
  
  <p><strong>DataContext and Entity</strong></p>
  
  <pre><code>[Database(Name = "TestDatabase")]
  public class EntitiesDataContext : DataContext
  {
      public EntitiesDataContext() :
          base(Settings.Default.TestDatabaseConnectionString, new AttributeMappingSource())
      {
      }
  }
  
  [Table(Name = "dbo.MyEntity")]
  public class MyEntity : EntityBase
  {
      private long _EntityID;
  
      [Column(Name = "EntityID", Storage = "_EntityID")]
      public override long ID
      {
          get { return _EntityID; }
          set { _EntityID = value; }
      }
  
      [Column] public string Title;
  }
  </code></pre>
  
  <p>The problem is the overriden <strong>ID</strong>. I made a lot of variation with different mapping attribute/property name setups, but it seems the problem is not the naming but the <strong>base class</strong>. And there is also a difference between .NET3.5 and .NET4.0.</p>
  
  <p>So, for the following statements, imagine a</p>
  
  <pre><code>using (var ctx = new EntitiesDataContext())
  {
      //statement
  }
  </code></pre>
  
  <p>around.</p>
  
  <p>And GetTable() is <code>GetTable&lt;MyEntity&gt;().</code></p>
  
  <p><strong>Fails</strong> means <em>Class member EntityBase.ID is unmapped.</em> exception. <strong>Works</strong> means the expected behavior.</p>
  
  <p>1 (in 3.5) WORKS:</p>
  
  <pre><code>var result = ctx.GetTable().Where(i => i.ID == 2).FirstOrDefault();</code></pre>
  
  <p>2 (in 3.5) <strong>FAILS</strong>:</p>
  
  <pre><code>var result = ctx.GetTable().FirstOrDefault(i => i.ID == 2);</code></pre>
  
  <p>3 (in 3.5) WORKS:</p>
  
  <pre><code>var result = ctx.GetTable().FirstOrDefault(i => i.ID.Equals(2));</code></pre>
  
  <p>4 (in 3.5) WORKS:</p>
  
  <pre><code>var result = ctx.GetTable().Where(i => true).FirstOrDefault(i => i.ID == 2);</code></pre>
  
  <p>5 (in 3.5) WORKS:</p>
  
  <pre><code>var result = ctx.GetTable().Where(i => i.ID == 2).FirstOrDefault();</code></pre>
  
  <p>6 (in 4.0) <strong>FAILS</strong>:</p>
  
  <pre><code>var result = ctx.GetTable().Where(i => i.ID == 2).FirstOrDefault()</code></pre>
  
  <p>7 (in 4.0) WORKS:</p>
  
  <pre><code>var result = ctx.GetTable().Where(i => i.ID.Equals(2)).FirstOrDefault();</code></pre>
  
  <p>8 (in 4.0) <strong>FAILS</strong> (redundant with 6)</p>
  
  <pre><code>var result = ctx.GetTable().FirstOrDefault(i => i.ID == 2);</code></pre>
  
  <p>9 (in 4.0) WORKS:</p>
  
  <pre><code>var result = ctx.GetTable().FirstOrDefault(i => i.ID.Equals(2));</code></pre>
  
  <p>10 (in 4.0) WORKS:</p>
  
  <pre><code>ctx.GetTable().Where(i => true).FirstOrDefault(i => i.ID == 2);</code></pre>
  
  <p><strong>So</strong>
  I cannot figure out why it fails where it fails. Especially, why this works</p>
  
  <pre><code>var result = ctx.GetTable().Where(i => true).FirstOrDefault(i => i.ID == 2);</code></pre>
  
  <p>if FirstOrDefault with predicate does not? And why Equals works where == is not. </p>
  
  <p>I was looking for some Equals and == difference description, but it does not give me the answer for Where(i => true)... thing.</p>
  
  <p>It seems that it's <strong>not about the query</strong> but the object initialization. Because:</p>
  
  <p>in 4.0 WORKS:</p>
  
  <pre><code>var result = ctx.GetTable().Where(i => i.ID == 2).Select(i => i.Title).FirstOrDefault();</code></pre>
  
  <p>but :)</p>
  
  <p>in 4.0 it's also WORKS:</p>
  
  <pre><code>var result = ctx.GetTable().FirstOrDefault();</code></pre>
  
  <p>So <strong>maybe not the object initialization</strong>?</p>
  
  <p>The SQL being built by LinqToSql is the <strong>same</strong> for == and Equals. Also the <strong>same</strong> for </p>
  
  <pre><code>Where(i =&gt; true).FirstOrDefault(i =&gt; i.ID == 2)
  </code></pre>
  
  <p>and</p>
  
  <pre><code>FirstOrDefault(i =&gt; i.ID == 2)
  </code></pre>
  
  <p>There is no SQL query until FirstOrDefault, and it builds the query correctly, as it expected. Where(i => true) just continues the expression building and FirstOrDefault predicate included in the SQL queries.</p>
  
  <p>I was looking for <strong>other reason in Reflector</strong> in <strong>MSIL</strong>, but found nothing special.</p>
  
  <p>Any guess? :)</p>
  
  <p>Thank you</p>
  
  <p><strong>####Continuation (in .NET4.0)</strong></p>
  
  <p>I set up 5 simple methods to easily check in <strong>reflector</strong>:</p>
  
  <pre><code>public void WithEquals(EntitiesDataContext ctx)
  {
      ctx.GetTable&lt;MyEntity&gt;().FirstOrDefault(i =&gt; i.ID.Equals(2));
  }
  
  public void WithFakeWhereAndOperator(EntitiesDataContext ctx)
  {
      ctx.GetTable&lt;MyEntity&gt;().Where(i =&gt; true).FirstOrDefault(i =&gt; i.ID == 2);
  }
  
  public void WithOperator(EntitiesDataContext ctx)
  {
      ctx.GetTable&lt;MyEntity&gt;().FirstOrDefault(i =&gt; i.ID == 2);
  }
  
  public void WithOperatorSelect(EntitiesDataContext ctx)
  {
      ctx.GetTable&lt;MyEntity&gt;().Where(i =&gt; i.ID == 2).Select(i =&gt; i).FirstOrDefault();
  }
  
  public void WithOperatorAndWhere(EntitiesDataContext ctx)
  {
      ctx.GetTable&lt;MyEntity&gt;().Where(i =&gt; i.ID == 2).FirstOrDefault();
  }
  </code></pre>
  
  <p>WithOperator and WithOperatorAndWhere fails, but here is the <strong>MSIL</strong> and what I see:</p>
  
  <p><strong>WithOperator</strong></p>
  
  <pre><code>  .method public hidebysig instance void WithOperator(class LinqToSqlTest.EntitiesDataContext ctx) cil managed
      {
          .maxstack 5
          .locals init (
              [0] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
              [1] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0001)
          L_0000: nop 
          L_0001: ldarg.1 
          L_0002: callvirt instance class [System.Data.Linq]System.Data.Linq.Table`1&lt;!!0&gt; [System.Data.Linq]System.Data.Linq.DataContext::GetTable&lt;class LinqToSqlTest.MyEntity&gt;()
          L_0007: ldtoken LinqToSqlTest.MyEntity
          L_000c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_0011: ldstr "i"
          L_0016: call class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter(class [mscorlib]System.Type, string)
          L_001b: stloc.0 
          L_001c: ldloc.0 
          L_001d: ldtoken instance int64 LinqToSqlTest.EntityBase::get_ID()
          L_0022: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
          L_0027: castclass [mscorlib]System.Reflection.MethodInfo
          L_002c: call class [System.Core]System.Linq.Expressions.MemberExpression [System.Core]System.Linq.Expressions.Expression::Property(class [System.Core]System.Linq.Expressions.Expression, class [mscorlib]System.Reflection.MethodInfo)
          L_0031: ldc.i4.2 
          L_0032: conv.i8 
          L_0033: box int64
          L_0038: ldtoken int64
          L_003d: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_0042: call class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object, class [mscorlib]System.Type)
          L_0047: call class [System.Core]System.Linq.Expressions.BinaryExpression [System.Core]System.Linq.Expressions.Expression::Equal(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.Expression)
          L_004c: ldc.i4.1 
          L_004d: newarr [System.Core]System.Linq.Expressions.ParameterExpression
          L_0052: stloc.1 
          L_0053: ldloc.1 
          L_0054: ldc.i4.0 
          L_0055: ldloc.0 
          L_0056: stelem.ref 
          L_0057: ldloc.1 
          L_0058: call class [System.Core]System.Linq.Expressions.Expression`1&lt;!!0&gt; [System.Core]System.Linq.Expressions.Expression::Lambda&lt;class [mscorlib]System.Func`2&lt;class LinqToSqlTest.MyEntity, bool&gt;&gt;(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.ParameterExpression[])
          L_005d: call !!0 [System.Core]System.Linq.Queryable::FirstOrDefault&lt;class LinqToSqlTest.MyEntity&gt;(class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt;, class [System.Core]System.Linq.Expressions.Expression`1&lt;class [mscorlib]System.Func`2&lt;!!0, bool&gt;&gt;)
          L_0062: pop 
          L_0063: ret 
      }
  </code></pre>
  
  <p><strong>WithFakeWhereAndOperator</strong></p>
  
  <pre><code> .method public hidebysig instance void WithFakeWhereAndOperator(class LinqToSqlTest.EntitiesDataContext ctx) cil managed
      {
          .maxstack 5
          .locals init (
              [0] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
              [1] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0001)
          L_0000: nop 
          L_0001: ldarg.1 
          L_0002: callvirt instance class [System.Data.Linq]System.Data.Linq.Table`1&lt;!!0&gt; [System.Data.Linq]System.Data.Linq.DataContext::GetTable&lt;class LinqToSqlTest.MyEntity&gt;()
          L_0007: ldtoken LinqToSqlTest.MyEntity
          L_000c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_0011: ldstr "i"
          L_0016: call class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter(class [mscorlib]System.Type, string)
          L_001b: stloc.0 
          L_001c: ldc.i4.1 
          L_001d: box bool
          L_0022: ldtoken bool
          L_0027: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_002c: call class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object, class [mscorlib]System.Type)
          L_0031: ldc.i4.1 
          L_0032: newarr [System.Core]System.Linq.Expressions.ParameterExpression
          L_0037: stloc.1 
          L_0038: ldloc.1 
          L_0039: ldc.i4.0 
          L_003a: ldloc.0 
          L_003b: stelem.ref 
          L_003c: ldloc.1 
          L_003d: call class [System.Core]System.Linq.Expressions.Expression`1&lt;!!0&gt; [System.Core]System.Linq.Expressions.Expression::Lambda&lt;class [mscorlib]System.Func`2&lt;class LinqToSqlTest.MyEntity, bool&gt;&gt;(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.ParameterExpression[])
          L_0042: call class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt; [System.Core]System.Linq.Queryable::Where&lt;class LinqToSqlTest.MyEntity&gt;(class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt;, class [System.Core]System.Linq.Expressions.Expression`1&lt;class [mscorlib]System.Func`2&lt;!!0, bool&gt;&gt;)
          L_0047: ldtoken LinqToSqlTest.MyEntity
          L_004c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_0051: ldstr "i"
          L_0056: call class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter(class [mscorlib]System.Type, string)
          L_005b: stloc.0 
          L_005c: ldloc.0 
          L_005d: ldtoken instance int64 LinqToSqlTest.EntityBase::get_ID()
          L_0062: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
          L_0067: castclass [mscorlib]System.Reflection.MethodInfo
          L_006c: call class [System.Core]System.Linq.Expressions.MemberExpression [System.Core]System.Linq.Expressions.Expression::Property(class [System.Core]System.Linq.Expressions.Expression, class [mscorlib]System.Reflection.MethodInfo)
          L_0071: ldc.i4.2 
          L_0072: conv.i8 
          L_0073: box int64
          L_0078: ldtoken int64
          L_007d: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_0082: call class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object, class [mscorlib]System.Type)
          L_0087: call class [System.Core]System.Linq.Expressions.BinaryExpression [System.Core]System.Linq.Expressions.Expression::Equal(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.Expression)
          L_008c: ldc.i4.1 
          L_008d: newarr [System.Core]System.Linq.Expressions.ParameterExpression
          L_0092: stloc.1 
          L_0093: ldloc.1 
          L_0094: ldc.i4.0 
          L_0095: ldloc.0 
          L_0096: stelem.ref 
          L_0097: ldloc.1 
          L_0098: call class [System.Core]System.Linq.Expressions.Expression`1&lt;!!0&gt; [System.Core]System.Linq.Expressions.Expression::Lambda&lt;class [mscorlib]System.Func`2&lt;class LinqToSqlTest.MyEntity, bool&gt;&gt;(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.ParameterExpression[])
          L_009d: call !!0 [System.Core]System.Linq.Queryable::FirstOrDefault&lt;class LinqToSqlTest.MyEntity&gt;(class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt;, class [System.Core]System.Linq.Expressions.Expression`1&lt;class [mscorlib]System.Func`2&lt;!!0, bool&gt;&gt;)
          L_00a2: pop 
          L_00a3: ret 
      }
  </code></pre>
  
  <p>As I see, there is no difference between the <strong>FirstOrDefault</strong> calls, the <strong>WithFakeWhereAndOperator</strong> only 'includes' a few line about the Where statement:</p>
  
  <p><img src="https://i.stack.imgur.com/7lwpO.jpg" alt="WithFakeWhereAndOperator and WithOperator difference"></p>
  
  <p>And the <strong>WithEquals</strong></p>
  
  <pre><code>.method public hidebysig instance void WithEquals(class LinqToSqlTest.EntitiesDataContext ctx) cil managed
      {
          .maxstack 7
          .locals init (
              [0] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
              [1] class [System.Core]System.Linq.Expressions.Expression[] CS$0$0001,
              [2] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0002)
          L_0000: nop 
          L_0001: ldarg.1 
          L_0002: callvirt instance class [System.Data.Linq]System.Data.Linq.Table`1&lt;!!0&gt; [System.Data.Linq]System.Data.Linq.DataContext::GetTable&lt;class LinqToSqlTest.MyEntity&gt;()
          L_0007: ldtoken LinqToSqlTest.MyEntity
          L_000c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_0011: ldstr "i"
          L_0016: call class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter(class [mscorlib]System.Type, string)
          L_001b: stloc.0 
          L_001c: ldloc.0 
          L_001d: ldtoken instance int64 LinqToSqlTest.EntityBase::get_ID()
          L_0022: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
          L_0027: castclass [mscorlib]System.Reflection.MethodInfo
          L_002c: call class [System.Core]System.Linq.Expressions.MemberExpression [System.Core]System.Linq.Expressions.Expression::Property(class [System.Core]System.Linq.Expressions.Expression, class [mscorlib]System.Reflection.MethodInfo)
          L_0031: ldtoken instance bool [mscorlib]System.Int64::Equals(int64)
          L_0036: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
          L_003b: castclass [mscorlib]System.Reflection.MethodInfo
          L_0040: ldc.i4.1 
          L_0041: newarr [System.Core]System.Linq.Expressions.Expression
          L_0046: stloc.1 
          L_0047: ldloc.1 
          L_0048: ldc.i4.0 
          L_0049: ldc.i4.2 
          L_004a: conv.i8 
          L_004b: box int64
          L_0050: ldtoken int64
          L_0055: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_005a: call class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object, class [mscorlib]System.Type)
          L_005f: stelem.ref 
          L_0060: ldloc.1 
          L_0061: call class [System.Core]System.Linq.Expressions.MethodCallExpression [System.Core]System.Linq.Expressions.Expression::Call(class [System.Core]System.Linq.Expressions.Expression, class [mscorlib]System.Reflection.MethodInfo, class [System.Core]System.Linq.Expressions.Expression[])
          L_0066: ldc.i4.1 
          L_0067: newarr [System.Core]System.Linq.Expressions.ParameterExpression
          L_006c: stloc.2 
          L_006d: ldloc.2 
          L_006e: ldc.i4.0 
          L_006f: ldloc.0 
          L_0070: stelem.ref 
          L_0071: ldloc.2 
          L_0072: call class [System.Core]System.Linq.Expressions.Expression`1&lt;!!0&gt; [System.Core]System.Linq.Expressions.Expression::Lambda&lt;class [mscorlib]System.Func`2&lt;class LinqToSqlTest.MyEntity, bool&gt;&gt;(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.ParameterExpression[])
          L_0077: call !!0 [System.Core]System.Linq.Queryable::FirstOrDefault&lt;class LinqToSqlTest.MyEntity&gt;(class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt;, class [System.Core]System.Linq.Expressions.Expression`1&lt;class [mscorlib]System.Func`2&lt;!!0, bool&gt;&gt;)
          L_007c: pop 
          L_007d: ret 
      }
  </code></pre>
  
  <p>The difference is bigger:</p>
  
  <p><img src="https://i.stack.imgur.com/etLBD.jpg" alt="WithOperator and WithEquals difference"></p>
  
  <p>In <strong>WithEquals</strong>, there is an extra </p>
  
  <pre><code>[System.Core]System.Linq.Expressions.Expression[]
  </code></pre>
  
  <p>initialization, and it calls Equals in the middle of the method.</p>
  
  <p>Also, I can see that <strong>WithOperator</strong> uses </p>
  
  <pre><code>call class [System.Core]System.Linq.Expressions.BinaryExpression [System.Core]System.Linq.Expressions.Expression::Equal(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.Expression)
  </code></pre>
  
  <p>while <strong>WithEquals</strong> uses</p>
  
  <pre><code>call class [System.Core]System.Linq.Expressions.MethodCallExpression [System.Core]System.Linq.Expressions.Expression::Call(class [System.Core]System.Linq.Expressions.Expression, class [mscorlib]System.Reflection.MethodInfo, class [System.Core]System.Linq.Expressions.Expression[])
  </code></pre>
  
  <p>This is in the <strong>line 38</strong> on the second image.</p>
  
  <p>Hm, maybe it's a problem about the difference between <strong>BinaryExpression</strong> and <strong>MethodCallExpression</strong>? I will make further research about these.</p>
  
  <p><strong>So on</strong></p>
  
  <p>We have a working</p>
  
  <pre><code>public void WithOperatorSelect(EntitiesDataContext ctx)
  {
      ctx.GetTable&lt;MyEntity&gt;().Where(i =&gt; i.ID == 2).Select(i =&gt; i).FirstOrDefault();
  }
  </code></pre>
  
  <p>Same as </p>
  
  <pre><code>public void WithOperatorAndWhere(EntitiesDataContext ctx)
  {
      ctx.GetTable&lt;MyEntity&gt;().Where(i =&gt; i.ID == 2).FirstOrDefault();
  }
  </code></pre>
  
  <p>but with an extra fake select and it <strong>works</strong>.</p>
  
  <p><strong>MSIL</strong></p>
  
  <p><strong>WithOperatorAndSelect</strong></p>
  
  <pre><code>.method public hidebysig instance void WithOperatorSelect(class LinqToSqlTest.EntitiesDataContext ctx) cil managed
      {
          .maxstack 5
          .locals init (
              [0] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
              [1] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0001)
          L_0000: nop 
          L_0001: ldarg.1 
          L_0002: callvirt instance class [System.Data.Linq]System.Data.Linq.Table`1&lt;!!0&gt; [System.Data.Linq]System.Data.Linq.DataContext::GetTable&lt;class LinqToSqlTest.MyEntity&gt;()
          L_0007: ldtoken LinqToSqlTest.MyEntity
          L_000c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_0011: ldstr "i"
          L_0016: call class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter(class [mscorlib]System.Type, string)
          L_001b: stloc.0 
          L_001c: ldloc.0 
          L_001d: ldtoken instance int64 LinqToSqlTest.EntityBase::get_ID()
          L_0022: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
          L_0027: castclass [mscorlib]System.Reflection.MethodInfo
          L_002c: call class [System.Core]System.Linq.Expressions.MemberExpression [System.Core]System.Linq.Expressions.Expression::Property(class [System.Core]System.Linq.Expressions.Expression, class [mscorlib]System.Reflection.MethodInfo)
          L_0031: ldc.i4.2 
          L_0032: conv.i8 
          L_0033: box int64
          L_0038: ldtoken int64
          L_003d: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_0042: call class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object, class [mscorlib]System.Type)
          L_0047: call class [System.Core]System.Linq.Expressions.BinaryExpression [System.Core]System.Linq.Expressions.Expression::Equal(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.Expression)
          L_004c: ldc.i4.1 
          L_004d: newarr [System.Core]System.Linq.Expressions.ParameterExpression
          L_0052: stloc.1 
          L_0053: ldloc.1 
          L_0054: ldc.i4.0 
          L_0055: ldloc.0 
          L_0056: stelem.ref 
          L_0057: ldloc.1 
          L_0058: call class [System.Core]System.Linq.Expressions.Expression`1&lt;!!0&gt; [System.Core]System.Linq.Expressions.Expression::Lambda&lt;class [mscorlib]System.Func`2&lt;class LinqToSqlTest.MyEntity, bool&gt;&gt;(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.ParameterExpression[])
          L_005d: call class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt; [System.Core]System.Linq.Queryable::Where&lt;class LinqToSqlTest.MyEntity&gt;(class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt;, class [System.Core]System.Linq.Expressions.Expression`1&lt;class [mscorlib]System.Func`2&lt;!!0, bool&gt;&gt;)
          L_0062: ldtoken LinqToSqlTest.MyEntity
          L_0067: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_006c: ldstr "i"
          L_0071: call class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter(class [mscorlib]System.Type, string)
          L_0076: stloc.0 
          L_0077: ldloc.0 
          L_0078: ldc.i4.1 
          L_0079: newarr [System.Core]System.Linq.Expressions.ParameterExpression
          L_007e: stloc.1 
          L_007f: ldloc.1 
          L_0080: ldc.i4.0 
          L_0081: ldloc.0 
          L_0082: stelem.ref 
          L_0083: ldloc.1 
          L_0084: call class [System.Core]System.Linq.Expressions.Expression`1&lt;!!0&gt; [System.Core]System.Linq.Expressions.Expression::Lambda&lt;class [mscorlib]System.Func`2&lt;class LinqToSqlTest.MyEntity, class LinqToSqlTest.MyEntity&gt;&gt;(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.ParameterExpression[])
          L_0089: call class [System.Core]System.Linq.IQueryable`1&lt;!!1&gt; [System.Core]System.Linq.Queryable::Select&lt;class LinqToSqlTest.MyEntity, class LinqToSqlTest.MyEntity&gt;(class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt;, class [System.Core]System.Linq.Expressions.Expression`1&lt;class [mscorlib]System.Func`2&lt;!!0, !!1&gt;&gt;)
          L_008e: call !!0 [System.Core]System.Linq.Queryable::FirstOrDefault&lt;class LinqToSqlTest.MyEntity&gt;(class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt;)
          L_0093: pop 
          L_0094: ret 
      }
  </code></pre>
  
  <p><strong>WithOperatorAndWhere</strong></p>
  
  <pre><code> .method public hidebysig instance void WithOperatorAndWhere(class LinqToSqlTest.EntitiesDataContext ctx) cil managed
      {
          .maxstack 5
          .locals init (
              [0] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
              [1] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0001)
          L_0000: nop 
          L_0001: ldarg.1 
          L_0002: callvirt instance class [System.Data.Linq]System.Data.Linq.Table`1&lt;!!0&gt; [System.Data.Linq]System.Data.Linq.DataContext::GetTable&lt;class LinqToSqlTest.MyEntity&gt;()
          L_0007: ldtoken LinqToSqlTest.MyEntity
          L_000c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_0011: ldstr "i"
          L_0016: call class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter(class [mscorlib]System.Type, string)
          L_001b: stloc.0 
          L_001c: ldloc.0 
          L_001d: ldtoken instance int64 LinqToSqlTest.EntityBase::get_ID()
          L_0022: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
          L_0027: castclass [mscorlib]System.Reflection.MethodInfo
          L_002c: call class [System.Core]System.Linq.Expressions.MemberExpression [System.Core]System.Linq.Expressions.Expression::Property(class [System.Core]System.Linq.Expressions.Expression, class [mscorlib]System.Reflection.MethodInfo)
          L_0031: ldc.i4.2 
          L_0032: conv.i8 
          L_0033: box int64
          L_0038: ldtoken int64
          L_003d: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
          L_0042: call class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object, class [mscorlib]System.Type)
          L_0047: call class [System.Core]System.Linq.Expressions.BinaryExpression [System.Core]System.Linq.Expressions.Expression::Equal(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.Expression)
          L_004c: ldc.i4.1 
          L_004d: newarr [System.Core]System.Linq.Expressions.ParameterExpression
          L_0052: stloc.1 
          L_0053: ldloc.1 
          L_0054: ldc.i4.0 
          L_0055: ldloc.0 
          L_0056: stelem.ref 
          L_0057: ldloc.1 
          L_0058: call class [System.Core]System.Linq.Expressions.Expression`1&lt;!!0&gt; [System.Core]System.Linq.Expressions.Expression::Lambda&lt;class [mscorlib]System.Func`2&lt;class LinqToSqlTest.MyEntity, bool&gt;&gt;(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.ParameterExpression[])
          L_005d: call class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt; [System.Core]System.Linq.Queryable::Where&lt;class LinqToSqlTest.MyEntity&gt;(class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt;, class [System.Core]System.Linq.Expressions.Expression`1&lt;class [mscorlib]System.Func`2&lt;!!0, bool&gt;&gt;)
          L_0062: call !!0 [System.Core]System.Linq.Queryable::FirstOrDefault&lt;class LinqToSqlTest.MyEntity&gt;(class [System.Core]System.Linq.IQueryable`1&lt;!!0&gt;)
          L_0067: pop 
          L_0068: ret 
      }
  </code></pre>
  
  <p>And the difference:</p>
  
  <p><img src="https://i.stack.imgur.com/jlQqe.jpg" alt="WithOperatorAndSelect and WithOperatorAndWhere difference"></p>
  
  <p>The only difference (in addition to that WithOperatorAndSelect works :) ) is the Select statement in MSIL.</p>
  
  <p>So I <em>guess</em> it's not an == operator / Equals problem. But I don't know.</p>