1

Я использую Entity Framework CTP 5 с «только кодом» (с SQL Server 2008). У меня есть объект, возвращенный из DbContext, из которого я потом получаю доступ к дочерней коллекции и выбираю из него один элемент. Вот мой LINQ заявление:Почему структура Entity Framework не добавляет «где» к SQL, сгенерированному при использовании SingleOrDefault?

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

Это приводит следующий SQL:

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 

Мое ограничение "IsCurrent" не ссылается на всех. IsCurrent - это бит в моей базе данных.

Может ли кто-нибудь объяснить, почему это так? Это вызывает огромный успех.

+0

не уверен ... x => x.IsCurrent == true – rene

ответ

4

Это по дизайну во всех реализациях EF. Сбор вопросов предоставляет IEnumerable<Question> не IQueryable<Question>. Когда вы обращаетесь к свойствам «Вопросы», запускается ленивая загрузка и загружаются все связанные вопросы. Затем вы вызываете SingleOrDefault на загруженную коллекцию.

Если вы хотите только один вопрос запустить этот запрос вместо:

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

Я думаю, потому что коллекция ребенок (currentTopic.Questions) лениво загружается полностью, а затем LINQ к объекту версии SingleOrDefault и не LINQ к объектам, которые вы вызываете в своей коллекции.

Выведенное SQL-заявление содержит WHERE [Extent1].[SessionId] = 24. Это показывает, что он загружает все вопросы для вашего currentTopic.