Em um post recente no seu blog, Stu Smith alegou que “LINQ-to-Entities vai retornar resultados diferentes dependendo de que queries anteriores você tenha executado!”. Se verdadeiro, isso tornaria usando o Framework Entity muito mais difícil de usar do que o necessário. Nós conversamos com Elisa Flasko do time do ADO.NET para descobrir o que realmente está acontecendo.
O caso aqui é na verdade um mal-entendido por parte do autor. A segunda query que eles executam, var order, é na verdade um query LINQ to Objects, não uma query LINQ to Entities (ou LINQ to SQL). A query LINQ to Objects está consultando os dados que foram trazidos anteriormente na memória pela primeira query, var alice.
Agora o motivo para a diferença nos resultados, é que o LINQ to SQL suporta Lazy Loading, enquanto a versão 1 do Entity Framework não suporta. Então se você olhar para a primeira query o autor apenas traz as entidades cliente na memória (em ambos os casos isso é verdade, tanto no LINQ to SQL quanto no LINQ to Entities). Contudo, na segunda query (orders) o autor tente acessar as entidades relacionadas Orders. Agora Lazy Loading fará então uma segunda visita ao database para obter esta informação, todavia o loading explícito no Entity Framework significa que não irá fazer visitas extras no database "através de mágica" para você. Considerando que os Orders não estão na memória, quando você executar a query LINQ to Objects em cima do LINQ to Entities não existirá resultados disponíveis no Orders. No entanto, depois do foreach (onde o autor chama especificamente data. Orders - acessando o contexto e consultando todos os Orders no database) os Orders agora estão na memória e portanto o LINQ to Objects pode usar uma query que faça uso deles.
Tudo que disse, nós estamos permitindo a você ativar o Lazy Loading em V2 do Entity Framework, porém ele continuará a ser desativado por padrão. O raciocínio por trás disso, é de assegurar que o desenvolvedor acidentalmente entre num problema de performance onde o database é atingido N+1 vezes, o que pode ser facilmente o caso com Lazy Loading, obrigando aos desenvolvedores que digam explicitamente ao framework que não estão preocupados com o impacto da performance no Lazy Loading.
Então este é um grande problema de design ou apenas uma questão de treinamento?