1

次のアイテムのリストがあるとしましょう。

List<Item> items = Item.GetSomeItems();

そして、アイテムのリストからIDを持つ特定のアイテムを取得したかったのです。

int itemID = 2;

次の方法のうち、アイテムを取得するための正しく適切な方法はどれですか?

Item item = items.Find(x => x.ItemID == itemID);

また

Item item items.Where(x => x.ItemID == itemID).FirstOrDefault();

たぶん、これらのどちらもLINQを使用する最良の解決策ではありません。いずれにせよ、私は個々のビジネスオブジェクトアイテムを頻繁に取得するので、最良のアプローチの説明が役立ちます。どの関数をいつ使用するかも素晴らしいでしょう。ありがとうございました。

4

3 に答える 3

4

Find()との実装の違いがわかりませんWhere()。偶然にも同じだと思いますが、選択したコレクションの実装に固有のメソッドではなく、LINQ 拡張メソッド ( など)Where()に固執することをお勧めします。Single[OrDefault]()これらは拡張メソッドであるため、IEnumerable<T>必要に応じて別のコレクション実装を選択する柔軟性が高くなります。

ボーナスポイント:

ただし、ここでいくつかのことが心配です-どこかから物をロードし、その後メモリ内でフィルタリングしています。私はもっ​​と似たものを見たいです:

Item item = Item.GetItemForId(2);

(おそらく)データベースにフィルタリングを任せます。それはおそらくSRPに違反していますが、実際には次に向かっています:

IRepository<Item> repository = this.itemRepository;
Item item = repository.Get(2);

完全な Linq to SQL/Entities を使用している場合は、遅延実行を利用して、次のようなことを行うことができます。

Item item = context.Items.SingleOrDefault(i => i.Id == 2);

これは、 を呼び出す前にすべてのアイテムをロードするわけSingleOrDefault()ではなく、代わりに who 式を調べて、次のような適切な SQL を生成します。

SELECT [fields] FROM Item WHERE Id = @id

これはすべて私の側の仮定ですが、データベースに送信する SQL ステートメントを作成するLinq to Entities (Entity Framework)Linq to SQLと、 Linq to Objectsには大きな違いがあることを明確にしたいと思いました。同じメソッド呼び出しですが、メモリ内のコレクション オブジェクトを操作します。

于 2012-05-24T15:29:08.890 に答える
3

指定された値がコレクションに存在しない可能性があり、それが例外的なケースではないことが予想.FirstOrDefault()される場合は、間違いなく2番目のケースを使用することをお勧めします。

また、はのFind()メソッドでありList<T>、代わりにWhere()拡張メソッドであり、を実装するすべてのタイプに適用できるため、コードで使用することにより、柔軟性が向上することにも注意してください。IEnumerable<T>Where()

于 2012-05-24T15:25:40.067 に答える
3

次のようなものを使用する必要があります。

Item item = items.FirstOrDefault(x => x.ItemID == itemID);

動作方法に応じて、使用する LINQ メソッドとして、Single、SingleOrDefault、First、および FirstOrDefault から選択します。リスト内の複数のアイテムがクエリに一致する場合、Single はエラーをスローします。First は、クエリに一致する最初のアイテムを返すだけです。OrDefault がないと、一致するものが見つからない場合にエラーがスローされ、その場合は null が返されます。これは、null を使用して null 参照例外を取得するよりも優れています。

たとえば、ItemID に一致するアイテムが 1 つだけ存在する場合のみを処理する場合は、Single を使用します。複数あることは無効ではなく、一致するものがないことを適切に処理したい場合は、FirstOrDefault を使用し、使用する前に結果の項目が null かどうかを確認してください。

于 2012-05-24T15:29:41.977 に答える