Почему Entity Framework не добавляет «где» к SQL, генерируемому при использовании SingleOrDefault? - PullRequest
1 голос
/ 01 марта 2011

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

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 - это битовое поле в моей базе данных.

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

Ответы [ 2 ]

4 голосов
/ 01 марта 2011

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

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

var question = context.Questions
                 .SingleOrDefault(q => q.Session.Id == sessionId && q.IsCurrent);
2 голосов
/ 01 марта 2011

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

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

...