InfoQ

News

Does LINQ-to-Entities really return different results depending on previous queries?

Posted by Jonathan Allen on Dec 03, 2008 03:10 PM

Community
.NET
Topics
Data Access
Tags
ADO.NET Entity Framework

In a recent blog post Stu Smith claimed that “LINQ-to-Entities will return different results depending on what previous queries you’ve executed!”. If true, this would make using Entity Framework much harder than necessary to use. We talked to Elisa Flasko of the ADO.NET Team to find out what’s really going on.

The case here is actually a misunderstanding on the part of the author. The second query that they author runs, var order, is actually a LINQ to Objects query, not a LINQ to Entities (or LINQ to SQL) query. The LINQ to Objects query is querying the data that was previously brought into memory by the first query, var alice.

Now the reason for the difference in results, is that LINQ to SQL supports Lazy Loading, while version 1 of the Entity Framework does not. So if you look at the first query the author only brings the customer entities into memory (in both LINQ to SQL and LINQ to Entities this is true). However, in the second query (orders) the author attempts to access the related Orders entities. Now Lazy Loading will then make a second trip to the database to retrieve this information, however the explicit loading in the Entity Framework means that it will not make extra trips to the database "magically" for you. Since the Orders are not in memory, when you execute the LINQ to Objects query on top of the LINQ to Entities results there are no Orders available. However, after the foreach (where the author specifically calls data.Orders - accessing the context and querying for all Orders in the database) the Orders are now in memory and therefore the LINQ to Objects can query over top of them.

All that said, we are enabling you to turn on Lazy Loading in V2 of the Entity Framework, however it will continue to be off by default. The reasoning behind this, is to ensure that a developer cannot accidently get themselves into a performance problem situation where the database is being hit N+1 times, which is can easily be case with Lazy Loading, rather they developer must explicitly tell the framework that they are not concerned about the performance impact of Lazy Loading.

So is this a major design problem or just a training issue?

Follow-Up by Stu Smith Posted Dec 4, 2008 9:12 AM
Re: Follow-Up by Eugene Tolmachev Posted Dec 8, 2008 10:09 AM
Training issue by Rui Craveiro Posted Feb 11, 2009 4:21 PM
  1. Back to top

    Follow-Up

    Dec 4, 2008 9:12 AM by Stu Smith

    I've put down a few more thoughts in a new article, in case anyone's interested: http://www.hackification.com/2008/12/04/linq-to-entities-follow-up/ - Stu

  2. Back to top

    Re: Follow-Up

    Dec 8, 2008 10:09 AM by Eugene Tolmachev

    If you read the answer carefully, LINQ-to-Entities not implementing the lazy loading is all it comes down to. Realizing that your objects are more-or-less PONOs, it makes perfect sense that any collection on a retrieved entity will support only LINQ-to-Objects, although in the absense of "lazy" one would expect "eager". I wish Microsoft didn't reinvent the wheel and instead implemented LINQ-to-NHibernate.

  3. Back to top

    Training issue

    Feb 11, 2009 4:21 PM by Rui Craveiro

    Hi, Actually, both. Not so obvious APIs become inevitably training issues. Whenever something doesn't work as expected, training can be argued, but training is a workaround, not the problem.

Educational Content

Bindings, Platforms, and Innovation

This presentation focuses on the Internet and separating myth from fact, history from the future, and the mundane from the imaginative. Bob Frankston presents a vision of what could and should be.

Orchestrating Long Running Activities with JBoss / JBPM

This article explores the use of JBoss and jBPM to implement design solutions that effectively address the issue of orchestrating long running activities.

Neo4j - The Benefits of Graph Databases

This presentation covers the use of graph databases as an optimal solution for data that is difficult to fit in static tables, rapidly evolving data or data that has a lot of optional attributes.

Realistic about Risk: Software development with Real Options

This session introduces Real Options and shows how it can help in running your project. Real Options is a decision-making process that can be used to manage risk.

Communication Flexibility Using Bindings

This article discusses the use of bindings on services and references (including the instance of non-configured bindings) as the means to implement SCA communications in a Web and SOA environment.

Writing DSLs in Groovy

After a short introduction to DSLs, Scott Davis plays with the keyboard showing how to approach the creation of a DSL by typing working snippets of Groovy code that get executed.

Scaling Agile with C/ALM (Collaborative Application Lifecycle Management)

IBM Rational and InfoQ present, Scaling Agile with C/ALM, an eBook showing organizations how to become “finely tuned software delivery machines” by enabling team integration and scaling.

Concurrent Programming with Microsoft F#

Amanda Laucher presents a real life enterprise application written in F#. She shows actual code snippets, explaining design decisions and suggesting how to use some of the F# constructs.