2012-08-07 7 views
30

Ich verwende EF4.0, und ich schrieb eine Abfrage:Warum SingleOrDefault Ergebnis TOP (2) in SQL?

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

Ich brauche nur ein Beitrag dieser Abfrage. Ich dachte SingleOrDefault() erzeugen wird "SELECT TOP (1) ...", aber wenn ich in SQL Profiler suchen, war es:

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' 

Ich frage mich, warum EF Ergebnis in SELECT TOP (2)? Ich brauche nur einen Beitrag.

+2

Und Sie könnten verwenden: 'var query = context.Post.SingleOrDefault (p => p.Id == postId);' – Malmi

+0

Wir verwenden NHibernate, die ich erwartet, dies zu tun, aber es nicht tut ... Es wählt alles ... Grrrrr ... –

Antwort

48

Es wählt Top 2 aus, so dass, wenn tatsächlich 2 oder mehr Datensätze in der Datenbank vorhanden sind, eine Ausnahme ausgelöst wird. Wenn es nur Top 1 auswählt, gibt es keine Möglichkeit zu einem Fehler.

17

Durch die SingleOrDefault einer Sequenz zu fragen, fragen Sie für dieses Verhalten:

  • , wenn die Sequenz genau 0 Elemente hat, kehren die default für den Elementtyp der Sequenz
  • , wenn die Sequenz genau hat 1 Element, senden Sie das Element
  • , wenn die Sequenz mehr als 1 Element hat, werfen

Doing a TOP (1) würde die ersten beiden Teile dieser, aber nicht die dritte befähigen. Nur durch einen TOP (2) können wir genau zwischen 1 Datensatz und mehr als 1 Datensatz unterscheiden.

Wenn Sie nicht wollen oder den dritten Teil des obigen Behaviours benötigen, verwenden Sie stattdessen .