1

J'utilise Entity Framework CTP 5 avec "code only" (avec SQL Server 2008). J'ai une entité retournée depuis un DbContext à partir de laquelle j'accède à une collection enfant, et en sélectionne un élément. Voici ma déclaration LINQ:Pourquoi Entity Framework n'ajoute pas de "where" au SQL généré lorsque SingleOrDefault est utilisé?

Question currentQuestion = currentTopic.Questions.SingleOrDefault(x => x.IsCurrent); 

Ce produit l'instruction SQL suivante:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[CreatedAt] AS [CreatedAt], 
[Extent1].[IsCurrent] AS [IsCurrent], 
[Extent1].[Xml] AS [Xml], 
[Extent1].[TopicId] AS [TopicId] 
FROM [dbo].[Questions] AS [Extent1] 
WHERE [Extent1].[SessionId] = 24 

Ma restriction "IsCurrent" n'est pas référencé du tout. IsCurrent est un champ de bits dans ma base de données.

Quelqu'un peut-il expliquer pourquoi c'est? Cela provoque un énorme coup de performance.

+0

pas sûr ... x => x.IsCurrent == true – rene

Répondre

4

Cela est inhérent à toutes les implémentations EF. La collection de questions expose IEnumerable<Question> et non IQueryable<Question>. Lorsque vous accédez à la propriété Questions, le chargement paresseux est déclenché et toutes les questions connexes sont chargées. Ensuite, vous appelez SingleOrDefault sur la collection chargée.

Si vous voulez juste courir seule question cette requête à la place:

var question = context.Questions 
       .SingleOrDefault(q => q.Session.Id == sessionId && q.IsCurrent); 
2

Je pense que la collection des enfants (currentTopic.Questions) est chargé paresseusement complètement puis la LINQ pour objet version de SingleOrDefault et non le LINQ aux entités on est appelé sur votre collection. L'instruction SQL que vous avez publiée contient WHERE [Extent1].[SessionId] = 24. Cela montre qu'il charge toutes les questions pour votre currentTopic.

Questions connexes