Entity Framework 4 Single()vs First()vs FirstOrDefault()


119

単一のアイテムをクエリするためのさまざまな方法の比較と、それぞれをいつ使用するかについて、時間の悪魔がいます。

誰かがこれらすべてを比較するリンクを持っていますか、またはなぜあなたが他のものを使うのかについての簡単な説明がありますか?私が知らないオペレーターがまだいますか?

ありがとうございました。

回答:


205

さまざまな方法の概要は次のとおりです。

  • Find()-主キーでアイテムを取得する場合。アイテムが見つからない場合はnullを返します。(コメントでYaronが指摘しているように)データベースに移動する前にコンテキストを調べます。これは、同じコンテキストが有効な間に同じエンティティを複数回取得する必要がある場合に重要な効率要素になる可能性があります。

  • Single()-クエリによって正確に1つのアイテムが返されることが期待される場合。これは、クエリが正確に1つのアイテムを返さない場合に例外をスローします。

  • SingleOrDefault()-クエリによってゼロまたは1つのアイテムが返されることが期待される場合(つまり、指定されたキーを持つアイテムが存在するかどうか不明)。クエリが0または1つのアイテムを返さない場合、これは例外をスローします。

  • First()-クエリによって1つ以上のアイテムが返されることが期待されているが、コード内の最初のアイテムのみにアクセスしたい場合(ここでのクエリでは順序が重要になる場合があります)。これは、クエリが少なくとも1つのアイテムを返さない場合に例外をスローします。

  • FirstOrDefault()-クエリから0個以上のアイテムが返されることを期待しているが、コードの最初のアイテムにのみアクセスしたい場合(つまり、指定されたキーを持つアイテムが存在するかどうか不明)


1
シナリオによって異なります。特定のクエリに対して、常にデータベースから単一のレコードを取得する必要があることがわかっている場合、それ以上でもそれ以下でもない場合、Single()を使用するのが「適切」です。他の状況では、他の状況がより適切な場合があります。EFの以前のバージョンでは、First()とFirstOrDefault()に制限されていました。これは、単一のレコードを期待しているシナリオで機能しますが、実際にはその単一のレコードよりも多く返されても警告しません。状況。
スティーブウィルコック

1
ありがとう。私は自分自身がFirst()を必要としていることをもう見ることができません。密度が低い場合でも、First()をいつ使用するかを理解できると確信しています。
asfsadf 2010

1
First()は、順序付け対象の最高または最低のオブジェクトのみを取得したい場合に最も意味があります。たとえば、合計値が最も高いセールを見つけてください。Sales.OrderByDescending(s => s.TotalValue).First();
Mike Chamberlain

5
すべてのコメントは重要な違いを見ています。Find()は、データベースにアクセスする前にコンテキストを検索する唯一のメソッドです。
Yaron Levi

5
もう1つのポイントは、SQLデータベースをクエリするとき、SingleまたはSingleOrDefault2つのレコードをクエリする(制限2)FirstFirstOrDefault、1 つをクエリする(制限1)ことです。
Bart Calixto 2015年

22

いつも使いがちFirstOrDefaultです。本当にパフォーマンスにこだわりたい場合はFirstOrDefault、EFで使用する必要があります。カバーの下ではSingleOrDefault、クエリでtop(2)を使用しています。これは、条件に一致する2番目の行があるかどうかを確認する必要があり、一致する場合は例外をスローするためです。基本的にSingleOrDefaultは、クエリが複数のレコードを返した場合に例外をスローする必要があると言っています。


5
あなたは今までの性能差を測定してきたFirstOrDefaultし、SingleOrDefault有意であると?ほとんどの場合、それは時期尚早の最適化だと思います。
スティーブン

使用する傾向がある、Single()または1つしか存在しないはずのSingleOrDefault()ものを返す場合。私がそうする理由は、正しく書かれていないクエリを作成してバグを見つけることです。少なくとも私の考えでは、これはシステム内のデータの一貫性を保つのに役立ちます。もちろん、これは遅くなりますが、それほど遅くはないと思います。私はその代金を払いたいと思っています。
mortb

15

非常に単純です。Single単一のアイテムを返し、アイテムがないか、複数ある場合は例外をスローします。First最初のアイテムを返すか、アイテムがない場合はスローします。FirstOrDefaultアイテムがない場合、最初のアイテムを返すか、デフォルト値(null指定されたタイプが参照タイプの場合)を返します。

これは、APIが想定している動作です。ただし、基礎となる実装では動作が異なる場合があることに注意してください。Entity Frameworkはこれに従いますが、LLBLGenのようなO / RM はnull呼び出し時にも戻ることができますFirstが、これは非常に奇妙なことです。これは、デザイナーIMOによる非常に奇妙な(そして頑固な)決定でした。


スティーブンに感謝します。私はまだあなたがなぜ一方を他方に使うのか疑問に思っていると思いますか?私はいつもFirstOrDefault()を使用してきましたが、私が見た多くの新しい例がなぜSingle()に切り替わったのか知りたく思いました。Single()に切り替える理由はありますか?同じことを達成する他の人がいますが、代わりに検討する必要がありますか?
asfsadf 2010

7
コードが「速く失敗する」ようにしたい場合、First()およびSingle()は、コードに期待される結果をより正確に伝えさせます(そうしないと失敗する可能性があります)
Frank Schwieterman

3
私はフランクに完全に同意します。それはまた意思伝達のことです。Single結果には1つの要素しかないと期待することを明確に表現しています。
スティーブン

8

4つの方法にはそれぞれ場所があります。実際には2つの異なる操作しかありません。

  • 最初-複数のアイテムを含む結果セットが必要です。そのセットの最初のアイテムを入手してください。
  • 単一-単一の結果が返されることを期待して、私にその項目を与えてください。

xxxxOrDefault()バージョンは、「空の結果セットを例外的な状況であると見なしたくない」と追加しただけです。


OK、First()がほとんど役に立たないように思えます。Single()が最初のオプションではないシナリオを考え出すのに苦労しています。あなたはたまたま手に持っているのですか?ありがとう。
asfsadf 2010

3
残念ながら、多くの開発者は純粋に防御策としてFirst()またはFirstOrDefault()を使用しており、実際の問題を隠す可能性がある場合は例外を回避すると考えています。
Matt H

3

反対に、次のように、これらのメソッドをコアロジックで分割できます。

  • メソッドはデータベースを直接クエリしますSingle()、SingleOrDefault()、First()、FirstOrDefault()
  • メソッドは、データベースに対してクエリを発行する前に、キャッシュ内の検索を実行しますFind()

一部のパフォーマンスの詳細については、特に2番目のケースでは、こちらをご覧ください。https//msdn.microsoft.com/en-us/data/hh949853.aspx?f = 255&MSPPError = -2147217396#3

さらに、最初のグループでは複雑なクエリを定義できますが、Find()メソッドを使用すると、検索にエンティティキーのみを提供できます。


0

Single()およびSingleOrDefault()は通常、IDなどの一意の識別子で使用されますが、First()またはFirstOrDefault()は通常、複数の結果を持つ可能性があるが「上位1」のみが必要なクエリに使用されます。

結果が返されない場合、Single()またはFirst()は例外をスローし、SingleOrDefault()およびFirstOrDefault()は例外をキャッチしてnullまたはdefault(ResultDataType)を返します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.