Note that there are some explanatory texts on larger screens.

plurals
  1. POInteresting Linq to SQL common base class behavior
    text
    copied!<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>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload