Подтвердить что ты не робот

Почему SingleOrDefault возвращает TOP (2) в SQL?

Я использую EF4.0, и я написал запрос:

var query = context.Post.Where(p => p.Id == postId).SingleOrDefault();

Мне нужно только одно сообщение из этого запроса. Я думал, что SingleOrDefault() будет генерировать "SELECT TOP (1)...", но когда я смотрю в SQL Profiler, это было:

exec sp_executesql N'SELECT TOP (2) 
[Extent1].[Id] AS [Id], 
[Extent1].[Title] AS [Title], 
[Extent1].[Slug] AS [Slug], 
[Extent1].[PubDate] AS [PubDate], 
[Extent1].[PostContent] AS [PostContent], 
[Extent1].[Author] AS [Author], 
[Extent1].[CommentEnabled] AS [CommentEnabled], 
[Extent1].[AttachmentId] AS [AttachmentId], 
[Extent1].[IsPublished] AS [IsPublished], 
[Extent1].[Hits] AS [Hits], 
[Extent1].[CategoryId] AS [CategoryId]
FROM [dbo].[Post] AS [Extent1]
WHERE [Extent1].[Id] = @p__linq__0',N'@p__linq__0 uniqueidentifier',@p__linq__0='ECD9F3BE-3CA9-462E-AE79-2B28C8A16E32'

Интересно, почему EF приводит к SELECT TOP (2)? Мне нужен только один пост.

4b9b3361

Ответ 1

Он выбирает верхнюю часть 2, так что если в базе данных фактически есть 2 или более двух записей, будет выбрано исключение. Если он выбирает только верхнюю часть 1, невозможно было бы отключить ошибку.

Ответ 2

Запросив последовательность SingleOrDefault последовательности, вы просите об этом:

  • если последовательность имеет ровно 0 элементов, верните default для типа элемента последовательности
  • если последовательность имеет ровно 1 элемент, верните элемент
  • если последовательность имеет более чем элемент 1, бросьте

Выполнение TOP (1) позволило бы задействовать первые две части этого, но не третье. Только делая TOP (2), мы можем различать ровно запись 1 и больше, чем запись 1.

Если вам не нужна или нужна третья часть вышеприведенного поведения, используйте FirstOrDefault.