Note that there are some explanatory texts on larger screens.

plurals
  1. POLINQ To Entities and Lazy Loading
    primarykey
    data
    text
    <p>In a <a href="http://www.hackification.com/2008/12/03/linq-to-entities-the-blackberry-storm-of-orms/" rel="nofollow noreferrer">controversial blog post</a> today, Hackification pontificates on what appears to be a bug in the new LINQ To Entities framework: </p> <blockquote> <p>Suppose I search for a customer:</p> <pre><code>var alice = data.Customers.First( c =&gt; c.Name == "Alice" ); </code></pre> <p>Fine, that works nicely. Now let’s see if I can find one of her orders:</p> <pre><code> var order = ( from o in alice.Orders where o.Item == "Item_Name" select o ).FirstOrDefault(); </code></pre> <p>LINQ-to-SQL will find the child row. LINQ-to-Entities will silently return nothing.</p> <p>Now let’s suppose I iterate through all orders in the database:</p> <pre><code>foreach( var order in data.Orders ) { Console.WriteLine( "Order: " + order.Item ); } </code></pre> <p>And now repeat my search:</p> <pre><code>var order = ( from o in alice.Orders where o.Item == "Item_Name" select o ).FirstOrDefault(); </code></pre> <p>Wow! LINQ-to-Entities is suddenly telling me the child object exists, despite telling me earlier that it didn’t!</p> </blockquote> <p>My initial reaction was that this had to be a bug, but after further consideration (and <a href="http://www.infoq.com/news/2008/12/Lazy-Loading" rel="nofollow noreferrer">backed up by the ADO.NET Team</a>), I realized that this behavior was caused by the Entity Framework not lazy loading the Orders subquery when Alice is pulled from the datacontext.</p> <p>This is because order is a LINQ-To-Object query:</p> <pre><code>var order = ( from o in alice.Orders where o.Item == "Item_Name" select o ).FirstOrDefault(); </code></pre> <p>And is not accessing the datacontext in any way, while his foreach loop:</p> <pre><code> foreach( var order in data.Orders ) </code></pre> <p>Is accessing the datacontext.</p> <p>LINQ-To-SQL actually created lazy loaded properties for Orders, so that when accessed, would perform another query, LINQ to Entities leaves it up to you to manually retrieve related data.</p> <p>Now, I'm not a big fan of ORM's, and this is precisly the reason. I've found that in order to have all the data you want ready at your fingertips, they repeatedly execute queries behind your back, for example, that linq-to-sql query above might run an additional query per row of Customers to get Orders.</p> <p>However, the EF not doing this seems to majorly violate the principle of least surprise. While it is a technically correct way to do things (You should run a second query to retrieve orders, or retrieve everything from a view), it does not behave like you would expect from an ORM.</p> <p><strong>So, is this good framework design? Or is Microsoft over thinking this for us?</strong> </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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