it-swarm-ja.tech

LINQ:フィルタ基準とともにSingleOrDefaultとFirstOrDefault()を使用する場合

IEnumerable拡張メソッドSingleOrDefault()FirstOrDefault()を考えてください

MSDNでは、SingleOrDefault と記述しています。

シーケンスの唯一の要素を返します。シーケンスが空の場合はデフォルト値を返します。シーケンス内に複数の要素がある場合、このメソッドは例外をスローします。

一方、MSDNの FirstOrDefault (おそらくOrderBy()またはOrderByDescending()を使用する場合、またはまったく使用しない場合)、

シーケンスの最初の要素を返します

クエリの例をいくつか考えてみましょう。これら2つの方法をいつ使用するかが必ずしも明確ではありません。

var someCust = db.Customers
.SingleOrDefault(c=>c.ID == 5); //unlikely(?) to be more than one, but technically COULD BE

var bobbyCust = db.Customers
.FirstOrDefault(c=>c.FirstName == "Bobby"); //clearly could be one or many, so use First?

var latestCust = db.Customers
.OrderByDescending(x=> x.CreatedOn)
.FirstOrDefault();//Single or First, or does it matter?

質問

LINQクエリでSingleOrDefault()FirstOrDefault()を使うことにした場合、どのような規則に従いますか

458
p.campbell

SingleOrDefault を使用するときはいつでも、クエリは最大で単一の結果になるはずであることを明確に述べます。一方、 FirstOrDefault を使用すると、クエリは任意の量の結果を返すことができますが、最初の結果のみを表示するように指定します。

私は個人的には意味が非常に異なることに気付き、期待される結果に応じて適切なものを使用すると読みやすさが向上します。

423
Bryan Menard

結果セットが0レコードを返す場合:

  • SingleOrDefaultは型のデフォルト値を返します(例:intのデフォルトは0です)
  • FirstOrDefaultは型のデフォルト値を返します

結果セットが1レコードを返す場合:

  • SingleOrDefaultはそのレコードを返します
  • FirstOrDefaultはそのレコードを返します

結果セットが多数のレコードを返す場合:

  • SingleOrDefaultは例外をスローします
  • FirstOrDefaultは最初のレコードを返します

結論:

結果セットに多数のレコードが含まれている場合に例外をスローしたい場合は、SingleOrDefaultを使用してください。

結果セットの内容にかかわらず、常に1つのレコードが必要な場合は、FirstOrDefaultを使用します。

532
Alex

がある

  • 意味的な違い
  • パフォーマンスの違い

ふたつの間に。

意味の違い:

  • FirstOrDefaultは、潜在的に倍数の最初の項目を返します(または、存在しない場合はデフォルト)。
  • SingleOrDefaultは単一の項目があると仮定してそれを返します(あるいは何も存在しない場合はデフォルト)。複数の品目が契約違反の場合、例外がスローされます。

パフォーマンスの違い

  • FirstOrDefaultは通常高速で、要素が見つかるまで繰り返しますが、見つからない場合は列挙型全体を繰り返すだけで済みます。多くの場合、アイテムを見つける可能性が高いです。

  • SingleOrDefaultは要素が1つしかないかどうかをチェックする必要があるため、常に列挙型全体を繰り返します。正確には、2番目の要素を見つけて例外をスローするまで繰り返します。しかし、ほとんどの場合、2番目の要素はありません。

まとめ

  • または個の項目がいくつあっても構わない場合はFirstOrDefaultを使用してください。アイテムをコレクションに追加する際の一意性を確認すると、それらのアイテムを検索するときに再度確認するには費用がかかりすぎる可能性があります。

  • パフォーマンスをあまり気にする必要がなく、単一の項目の仮定が読者にとって明らかであり、実行時にチェックされるようにしたい場合は、SingleOrDefaultを使用してください。

実際には、パフォーマンスを向上させるために、単一の項目を想定している場合でもFirst/FirstOrDefaultを使用することがよくあります。 Single/SingleOrDefaultは読みやすさ(単一の項目を前提としているため)と安定性(それをチェックするため)を向上させ、適切に使用することができます。

227

SQLで翻訳されたFirstOrDefaultがTOP 1レコードを実行し、SingleOrDefaultがTOP 2レコードを実行するとは誰も言及していません。

70
shalke

LINQ - > SQLの場合:

SingleOrDefault

  • 「user * = 1のユーザーからselect *」のようなクエリを生成します。
  • 一致するレコードを選択し、複数のレコードが見つかった場合は例外を投げます
  • 主キー列または一意キー列に基づいてデータを取得している場合に使用します。

FirstOrDefault

  • 「userid = 1のユーザーからtop 1 *を選択」のようなクエリを生成します。
  • 最初に一致する行を選択
  • 非主キー列または一意キー列に基づいてデータをフェッチしている場合に使用します。
12
Prakash

私のロジックでは結果が0または1になることが要求される状況ではSingleOrDefaultを使用します。もっとある場合、それはエラー状況です。これは役に立ちます。

10
spender

SingleOrDefault: "最大で"クエリまたはデフォルトに一致するアイテムが1つあると言っているFirstOrDefault:クエリまたはデフォルトに一致する "少なくとも" 1つのアイテムがあると言っている

あなたが選ぶ必要がある次の時に大声で言うとあなたはおそらく賢明に選ぶでしょう。 :)

5
Steven

あなたのケースでは、私は以下を使います:

iD == 5で選択:ここでSingleOrDefaultを使用しても構いません。ID5を持つエンティティが複数ある場合は、1つの[またはなし]エンティティが予想されるため、間違いがあり、間違いなく例外的な価値があります。

名前が "Bobby"と等しい人を検索するときは、1つ以上の名前がある可能性があります(おそらく "Single"も "First"も使用しないでください)。エンティティの場合、ユーザーは検索を絞り込むか、返された結果の1つを選択する必要があります。

作成日順の並べ替えもWhere操作で実行する必要があります(エンティティが1つしかない可能性が高いので、並べ替えはあまり役に立ちません)。ただし、すべてのエンティティを並べ替えたい場合は、FirstOrDefaultを使用します。複数のエンティティを取得した場合、Singleは毎回スローします。

4
Olli

あなたの最後の例では:

var latestCust = db.Customers
.OrderByDescending(x=> x.CreatedOn)
.FirstOrDefault();//Single or First, or doesn't matter?

はい、そうです。 SingleOrDefault()を使用しようとしたときにクエリの結果がレコード以上になった場合は、例外が発生します。あなたがSingleOrDefault()を安全に使うことができる唯一の時はあなたがたった1つそして1つだけの結果を期待している時です...

3
bytebender

どちらも要素演算子であり、シーケンスから単一の要素を選択するために使用されます。しかし、それらの間には小さな違いがあります。 SingleOrDefault()演算子は、FirstOrDefault()が同じ例外をスローしないという条件を複数の要素が満たす場合に例外をスローします。これがその例です。

List<int> items = new List<int>() {9,10,9};
//Returns the first element of a sequence after satisfied the condition more than one elements
int result1 = items.Where(item => item == 9).FirstOrDefault();
//Throw the exception after satisfied the condition more than one elements
int result3 = items.Where(item => item == 9).SingleOrDefault();
3

私が今理解しているように、あなたがユニークであることが保証されているデータ、すなわち主キーのようなDB制約によって強制されているデータについて質問しているならSingleOrDefaultは良いでしょう。

あるいは、主キーを照会するためのより良い方法があります。

私のTableAccが持っていると仮定

AccountNumber - Primary Key, integer
AccountName
AccountOpenedDate
AccountIsActive
etc.

AccountNumber 987654を問い合わせたいのですが、

var data = datacontext.TableAcc.FirstOrDefault(obj => obj.AccountNumber == 987654);
1
M G

GitHubのさまざまな方法の使用方法についてGoogleに問い合わせました。これは、各メソッドに対してGoogle検索クエリを実行し、クエリ "site:github.com file:cs ..."を使用して、クエリをgithub.comドメインと.csファイル拡張子に限定することによって行われます。

FirstメソッドはSingleメソッドよりも一般的に使用されているようです。

| Method               | Results |
|----------------------|---------|
| FirstAsync           |     315 |
| SingleAsync          |     166 |
| FirstOrDefaultAsync  |     357 |
| SingleOrDefaultAsync |     237 |
| FirstOrDefault       |   17400 |
| SingleOrDefault      |    2950 |
0
Fred