Why SingleOrDefault result TOP(2) in SQL?
Entity FrameworkTsqlEntity Framework Problem Overview
I am using EF4.0, and I wrote a query:
var query = context.Post.Where(p => p.Id == postId).SingleOrDefault();
I need only One post from this query. I thought SingleOrDefault() will generate "SELECT TOP(1) ...", but when I look into SQL Profiler, It was:
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'
I wonder why EF result in SELECT TOP (2)? I only need one post.
Entity Framework Solutions
Solution 1 - Entity Framework
It selects top 2 so that if there are actually 2 or more than 2 records in the database, an exception would be thrown. If it only selects top 1 there would be no way to error out.
Solution 2 - Entity Framework
By asking for the SingleOrDefault
of a sequence, you are asking for this behaviour:
- if the sequence has exactly
0
elements, return thedefault
for the sequence's element type - if the sequence has exactly
1
element, return the element - if the sequence has more than
1
element, throw
Doing a TOP (1)
would empower the first two parts of this, but not the third. Only by doing a TOP (2)
can we differentiate between exactly 1
record and more than 1
record.
If you don't want or need the third part of the above behviour, instead use FirstOrDefault
.