2012-08-07 22 views
30

私はEF4.0を使用しています、と私は、クエリを書いた:SingleOrDefaultがSQLでTOP(2)を返すのはなぜですか?

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

私はこのクエリからわずか1ポストを必要としています。

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' 

私はSELECT TOP(2)中、なぜEF結果を疑問に思う:?私はSingleOrDefault()は、 "...(1)TOPを選択" が発生しますが、私はSQLプロファイラに見たとき、それは思いましたか私は1つの投稿が必要です。

+2

'var query = context.Post.SingleOrDefault(p => p.Id == postId);' – Malmi

+0

私はこれを行うと予想されていたNHibernateを使用していますが、 ...それはすべてを選択... Grrrrr ... –

答えて

48

データベースに2つ以上のレコードが実際に存在する場合、例外がスローされるようにトップ2が選択されます。トップ1のみを選択した場合、エラーを出力する方法はありません。あなたは、この動作のために求めているシーケンスのSingleOrDefaultを求めることで

17

、:

  • シーケンスは正確に0要素を持っている場合、シーケンスが正確に持っている場合、シーケンスの要素の型
  • ためdefaultを返します1要素、シーケンス以上1要素を持っている場合、スロー要素
  • を返す

TOP (1)を実行すると、これの最初の2つの部分が強化されますが、3番目の部分は強化されません。 TOP (2)を実行するだけで、正確に1レコードと1レコードの間を区別できます。

がありません。上記の動作の第3部が必要な場合は、FirstOrDefaultを使用してください。