InfoQ

InfoQ

News

My Bookmarks

Login or Register to enable bookmarks for unlimited time.

The content has been bookmarked!

There was an error bookmarking this content! Please retry.

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

Posted by Jonathan Allen on Dec 03, 2008

Sections
Architecture & Design,
Development,
Operations & Infrastructure
Topics
.NET ,
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
Re: Follow-Up by Eugene Tolmachev Posted
Training issue by Rui Craveiro Posted
  1. Back to top

    Follow-Up

    by Stu Smith

    I've put down a few more thoughts in a new article, in case anyone's interested:

    www.hackification.com/2008/12/04/linq-to-entiti...

    - Stu

  2. Back to top

    Re: Follow-Up

    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

    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

Collaboration: At the Extremities of Extreme

Jason Ayers share the observations he made watching a team of developers collaborating in real time on the same code base, pushing XP, pair programming and continuous integration to their extremes.

Yesod Web Framework

Michael Snoyman presents Yesod, a web framework written in Haskell and containing a web server, templating, ORM, libraries (templating, gravatar, etc.).

Transactions without Transactions

Richard Kreuter and Kyle Banker on how to avoid classical RDBMS transactional systems by using compensation mechanisms, transactional messaging or transactional procedures.

Attila Szegedi on JVM and GC Performance Tuning at Twitter

Attila Szegedi talks about performance tuning Java and Scala programs at Twitter: how to approach GC problems, the importance of asynchronous I/O, when to use MySQL/Cassandra/Redis, and much more.

10 tips on how to prevent business value risk

One category of risk that project teams need to ensure they address is business value failure – delivering a product that fails to provide value for the business investor.

Interview: Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives

InfoQ spoke to the authors of Software Systems Architecture on a couple of new topics, the System Context viewpoint and Agile, which have been added to the second edition.

Beauty Is in the Eye of the Beholder

Alex Papadimoulis discusses ugly code, where it comes from, how to avoid it, and how to get rid of it.

Architecting Visa for Massive Scale and Continuous Innovation

John Davies examines Visa’s architecture and shows how enterprises have architected complex integrations incorporating Hadoop, memcached, Ruby on Rails, and others to deliver innovative solutions.