56

私は EF4.0 を使用しており、次のクエリを作成しました。

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

このクエリからの投稿は 1 つだけ必要です。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) になるのだろうか? 必要なポストは 1 つだけです。

4

2 に答える 2

81

データベースに実際に 2 つ以上のレコードがある場合に例外がスローされるように、上位 2 つを選択します。上位 1 のみを選択する場合、エラーになる方法はありません。

于 2012-08-07T04:11:13.387 に答える
34

シーケンスの を要求SingleOrDefaultすると、次の動作が要求されます。

  • シーケンスが正確に要素を持つ場合、シーケンスの要素タイプの を0返しますdefault
  • シーケンスが正確に要素を持っている場合、その1要素を返します
  • シーケンスに複数の1要素がある場合、スローします

を実行するTOP (1)と、この最初の 2 つの部分が強化されますが、3 番目の部分は強化されません。a を実行することによってのみ、正確な記録と記録以上TOP (2)を区別できます。11

上記の動作の 3 番目の部分が不要または必要ない場合は、代わりに を使用してFirstOrDefaultください。

于 2012-08-07T08:20:41.230 に答える