web-dev-qa-db-ja.com

LINQで.Firstを使用する場合と.FirstOrDefaultを使用する場合

.Firstをいつ使用したいのか、またLINQで.FirstOrDefaultを使用したいのかについて、私は調べてみましたが、明確な答えを実際には見つけていません。

  • いつ.Firstを使用しますか?結果が返されない場合に、例外をキャッチしたい場合にのみ使用します。

    var result = List.Where(x => x == "foo").First();
    
  • そしていつ.FirstOrDefaultを使いたいですか?結果が得られない場合は、いつでもデフォルトの型が必要ですか。

    var result = List.Where(x => x == "foo").FirstOrDefault();
    
  • そしてそのことについては、Takeはどうですか?

    var result = List.Where(x => x == "foo").Take(1);
    
758
Metro Smurf

シーケンスが少なくとも1つの要素を持つことを知っている、または期待する場合は、First()を使用します。言い換えれば、シーケンスが空であることが例外的な出来事であるとき。

要素があるかどうかを確認する必要があることがわかっている場合はFirstOrDefault()を使用してください。言い換えれば、シーケンスが空であることが正当な場合です。チェックを例外処理に頼るべきではありません。 (これは悪い習慣であり、パフォーマンスを損なう可能性があります)。

最後に、First()Take(1)の違いは、First()は要素そのものを返すのに対し、Take(1)は正確に1つの要素を含む要素のシーケンスを返すということです。

752
driis

結果がない場合.Firstは例外をスローします。 .FirstOrDefaultしないでください、それは単にnull(参照型)または値型のデフォルト値を返します。 (intの場合は0のように)ここでの質問はあなたがデフォルトの型が欲しいときではありませんが、もっと:あなたは例外を処理することを望みますかそれともデフォルト値を処理しますか?例外は例外的なはずなので、クエリから結果を取得するかどうかわからない場合はFirstOrDefaultをお勧めします。論理的にデータがあるはずの場合は、例外処理を検討できます。

Skip()Take()は通常、結果のページングを設定するときに使用されます。 (最初の10件の結果を表示し、次の10件を次のページに表示するなど)

お役に立てれば。

256
Jeroen Landheer

.First()は、返す行がない場合に例外をスローします。一方、.FirstOrDefault()は、デフォルト値(すべての参照型に対してNULL)を代わりに返します。

ですから、可能性のある例外を処理しても構わないと思っているのであれば、.First()は問題ありません。とにかく!= nullの戻り値を確認したい場合は、.FirstOrDefault()が最適です。

しかし、私もそれが個人的な好みであると思います。どちらを使うかはあなたにとってより理にかなっていて、あなたのコーディングスタイルによりよく合っています。

102
marc_s

最初()

  1. シーケンスの最初の要素を返します。
  2. 結果に要素がないかソースがnullの場合、エラーが発生します。
  3. 一つ以上の要素が予想され、最初の要素だけが欲しいなら、あなたはそれを使うべきです。

FirstOrDefault()

  1. シーケンスの最初の要素を返します。要素が見つからない場合はデフォルト値を返します。
  2. ソースがnullの場合にのみエラーをスローします。
  3. 一つ以上の要素が予想され、最初の要素だけが欲しいなら、あなたはそれを使うべきです。結果が空の場合も良いです。

以下に示すように、いくつかのレコードを持つUserInfosテーブルがあります。以下のこの表に基づいて、私は例を作成しました...

UserInfo Table

First()の使い方

var result = dc.UserInfos.First(x => x.ID == 1);

ID == 1のレコードは1つだけです。このレコードを返す必要があります
ID:1の名前:Manish姓:Dubey Eメール:[email protected]

var result = dc.UserInfos.First(x => x.FName == "Rahul");   

FName == "Rahul"のレコードが複数あります。最初のレコードは返却する必要があります。
ID:7名前:Rahul姓:Sharma Eメール:[email protected]

var result = dc.UserInfos.First(x => x.ID ==13);

ID == 13のレコードはありません。エラーが発生するはずです。
InvalidOperationException:シーケンスに要素が含まれていません

FirstOrDefault()の使い方

var result = dc.UserInfos.FirstOrDefault(x => x.ID == 1);

ID == 1のレコードは1つだけです。このレコードを返す必要があります
ID:1の名前:Manish姓:Dubey Eメール:[email protected]

var result = dc.UserInfos.FirstOrDefault(x => x.FName == "Rahul");

FName == "Rahul"のレコードが複数あります。最初のレコードは返却する必要があります。
ID:7名前:Rahul姓:Sharma Eメール:[email protected]

var result = dc.UserInfos.FirstOrDefault(x => x.ID ==13);

ID == 13のレコードはありません。戻り値はnullです。

First()またはFirstOrDefault()をいつ使うべきか理解するのに役立つことを願っています。

60
Mukesh Kumar

まず第一に、Takeは全く異なる方法です。単一のTではなくIEnumerable<T>を返すので、これで終わりです。

FirstFirstOrDefaultの間では、要素が存在すると確信できる場合はFirstを使用し、存在しない場合はエラーになります。

ところで、シーケンスにdefault(T)要素(例:null)が含まれていて、最初の要素が空であることとnullであることを区別する必要がある場合は、FirstOrDefaultを使用できません。

18
Mehrdad Afshari

最初:

  • シーケンスの最初の要素を返します
  • 例外をスローします。結果に要素はありません
  • 次の場合に使用します。複数の要素が必要で、最初の要素のみが必要な場合

FirstOrDefault:

  • シーケンスの最初の要素を返します。要素が見つからない場合はデフォルト値を返します。
  • 例外が発生します。ソースがnullの場合のみ
  • 次の場合に使用します。複数の要素が必要で、最初の要素のみが必要な場合。結果が空でも問題ありません

から: http://www.technicaloverload.com/linq-single-vs-singleordefault-vs-first-vs-firstordefault/ /

13
user2051770

注意すべきもう1つの違いは、プロダクション環境でアプリケーションをデバッグしている場合は行番号にアクセスできない可能性があるため、メソッド内のどの特定の.First()文で例外がスローされたかを特定するのは難しい場合があります。

例外メッセージには、使用した可能性のあるLambda式も含まれていないため、デバッグが難しくなります。

そのため、nullエントリが例外的な状況になることがわかっていても、FirstOrDefault()を常に使用しています。

var customer = context.Customers.FirstOrDefault(i => i.Id == customerId);
if (customer == null)
{
   throw new Exception(string.Format("Can't find customer {0}.", customerId));
}
7
Kye

最初()

その結果が予想される複数の要素を含んでいることがわかっていて、sequenceの最初の要素だけを使うべきです。

FirstOrDefault()

FirstOrDefault()はFirst()と同じですが、指定された条件に一致する要素がない場合は、基になるジェネリックコレクションの型のデフォルト値が返される点が異なります。要素が見つからない場合、InvalidOperationExceptionはスローされません。しかし、要素またはシーケンスのコレクションは、例外をスローするよりもnullです。

4
Nimesh khatri

私はFirstOrDefaultの必要性を説明するように訴えるウェブサイトを見つけました
http://thepursuitofalife.com/the-linq-firstordefault-method-and-null-resultsets/ /
クエリに結果がなく、First()またはSingle()を呼び出して単一行を取得したい場合... "シーケンスに要素が含まれていません"という例外が発生します。

免責事項:私はLINQを使用したことがないので、これがマークから大きく外れているのであれば私の謝罪。

3
NULL
someList.First(); // exception if collection is empty.
someList.FirstOrDefault(); // first item or default(Type)

どれを使う?それはビジネスロジックによって決定されるべきで、例外/プログラムの失敗の恐れではありません。

例えば、もしビジネスロジックがどの仕事日にもトランザクションをゼロにすることはできないと言っているのであれば(ただ仮定)。それからあなたはいくつかのスマートなプログラミングでこのシナリオを処理しようとするべきではありません。私はいつもFirst()をそのようなコレクションの上で使います、そして何か他のものがビジネスロジックを台無しにしたならプログラムを失敗させます。

コード:

var transactionsOnWorkingDay = GetTransactionOnLatestWorkingDay();
var justNeedOneToProcess = transactionsOnWorkingDay.First(): //Not FirstOrDefault()

これについて他の人のコメントを見たいのですが。

2

このタイプの関数は要素演算子に属します。いくつかの便利な要素演算子を以下に定義します。

  1. First/FirstOrDefault
  2. Last/LastOrDefault
  3. シングル/シングルまたはデフォルト

特定の条件に基づいてシーケンスから単一の要素を選択する必要がある場合は、要素演算子を使用します。これが一例です。

  List<int> items = new List<int>() { 8, 5, 2, 4, 2, 6, 9, 2, 10 };

First()演算子は、条件が満たされた後でシーケンスの最初の要素を返します。要素が見つからない場合は、例外がスローされます。

int result = items.Where(item => item == 2).First();

FirstOrDefault()演算子は、条件が満たされた後でシーケンスの最初の要素を返します。要素が見つからない場合は、その型のデフォルト値を返します。

int result1 = items.Where(item => item == 2).FirstOrDefault();

2

[OK]を私に2セントを与えましょう。 First/Firstまたはdefaultは、2番目のコンストラクタを使用するときのものです。それが何であるかは説明しませんが、例外を起こしたくないため、常に使用する可能性があるときです。

person = tmp.FirstOrDefault(new Func<Person, bool>((p) =>
{
    return string.IsNullOrEmpty(p.Relationship);
}));
1
Arian