2012-08-07 11 views
30

Sto usando EF4.0, e ho scritto una query:Perché il risultato SingleOrDefault TOP (2) in SQL?

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

ho bisogno di un solo post da questa query. Ho pensato SingleOrDefault() genererà "SELECT TOP (1) ...", ma quando guardo in SQL Profiler, è stato:

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' 

mi chiedo il motivo per cui risultato EF in SELEZIONATE TOP (2)? Ho solo bisogno di un post.

+2

E si può usare: 'var query = context.Post.SingleOrDefault (p => p.Id == postId);' – Malmi

+0

Stiamo usando NHibernate, cosa che mi aspettavo di fare, ma non ... Seleziona tutto ... Grrrrr ... –

risposta

48

Seleziona il primo 2 in modo che se ci sono effettivamente 2 o più di 2 record nel database, verrà generata un'eccezione. Se seleziona solo la prima parte non ci sarebbe modo di uscire.

17

Chiedendo la SingleOrDefault di una sequenza, si stanno chiedendo per questo comportamento:

  • se la sequenza ha esattamente 0 elementi, restituire il default per l'elemento della sequenza di tipo
  • se la sequenza ha esattamente 1 elemento, restituire l'elemento
  • se la sequenza ha più di 1 elemento, gettare

Fare un TOP (1) autorizzerebbe le prime due parti di questo, ma non il terzo. Solo facendo un TOP (2) possiamo distinguere tra esattamente il record 1 e oltre il record 1.

Se si non si desidera o si richiede la terza parte del messaggio precedente, utilizzare invece FirstOrDefault.

Problemi correlati