620 Stimmen

LINQ: Wann wird SingleOrDefault vs. FirstOrDefault() mit Filterkriterien verwendet?

Betrachten Sie die IEnumerable-Erweiterungsmethoden SingleOrDefault() et FirstOrDefault()

MSDN dokumentiert, dass SingleOrDefault :

Gibt das einzige Element einer Sequenz zurück oder einen Standardwert, wenn die Sequenz leer ist; diese Methode löst eine Ausnahme aus, wenn es mehr als ein Element in der Sequenz gibt.

während FirstOrDefault von MSDN (vermutlich bei Verwendung eines OrderBy() oder OrderByDescending() oder gar keine),

Gibt das erste Element einer Sequenz zurück

Bei einer Handvoll Beispielabfragen ist nicht immer klar, wann diese beiden Methoden zu verwenden sind:

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?

Frage

Welche Konventionen befolgen Sie oder schlagen Sie vor bei der Entscheidung über die Verwendung SingleOrDefault() et FirstOrDefault() in Ihren LINQ-Abfragen?

715voto

Alex Punkte 6833

Wenn Ihre Ergebnismenge 0 Datensätze liefert:

  • SingleOrDefault gibt den Standardwert für den Typ zurück (z. B. ist der Standardwert für int 0)
  • FirstOrDefault gibt den Standardwert für den Typ

Wenn Ihre Ergebnismenge 1 Datensatz liefert:

  • SingleOrDefault gibt diesen Datensatz zurück
  • FirstOrDefault gibt diesen Datensatz zurück

Wenn Ihre Ergebnismenge viele Datensätze liefert:

  • SingleOrDefault löst eine Ausnahme aus
  • FirstOrDefault gibt den ersten Datensatz zurück

Schlussfolgerung:

Wenn Sie möchten, dass eine Ausnahme ausgelöst wird, wenn die Ergebnismenge viele Datensätze enthält, verwenden Sie SingleOrDefault .

Wenn Sie immer 1 Datensatz haben wollen, egal was die Ergebnismenge enthält, verwenden Sie FirstOrDefault

547voto

Bryan Menard Punkte 12788

Wann immer Sie SingleOrDefault geben Sie eindeutig an, dass die Abfrage höchstens eine einzeln Ergebnis. Andererseits, wenn FirstOrDefault verwendet wird, kann die Abfrage eine beliebige Anzahl von Ergebnissen zurückgeben, aber Sie geben an, dass Sie nur das erste Ergebnis haben wollen.

Ich persönlich finde, dass die Semantik sehr unterschiedlich ist und dass die Verwendung der richtigen, von den erwarteten Ergebnissen abhängigen, die Lesbarkeit verbessert.

312voto

Stefan Steinegger Punkte 62197

Es gibt

  • ein semantischer Unterschied
  • ein Leistungsunterschied

zwischen den beiden.

Semantischer Unterschied:

  • FirstOrDefault gibt ein erstes Element von möglicherweise mehreren zurück (oder den Standardwert, wenn keiner existiert).
  • SingleOrDefault geht davon aus, dass es ein einziges Element gibt, und gibt es zurück (oder den Standardwert, wenn es keines gibt). Mehrere Elemente sind eine Verletzung des Vertrags, eine Ausnahme wird ausgelöst.

Leistungsunterschied

  • FirstOrDefault ist in der Regel schneller, da es so lange iteriert, bis es das Element findet, und nur dann die gesamte Aufzählung iterieren muss, wenn es das Element nicht findet. In vielen Fällen besteht eine hohe Wahrscheinlichkeit, ein Element zu finden.

  • SingleOrDefault muss prüfen, ob es nur ein Element gibt, und durchläuft daher immer die gesamte Aufzählung. Um genau zu sein, durchläuft es die Aufzählung so lange, bis es ein zweites Element findet und eine Ausnahme auslöst. Aber in den meisten Fällen gibt es kein zweites Element.

Schlussfolgerung

  • Utilice FirstOrDefault wenn es Ihnen egal ist, wie viele Artikel es gibt oder wenn Sie es sich nicht leisten können, die Einzigartigkeit zu prüfen (z. B. bei einer sehr großen Sammlung). Wenn Sie die Einzigartigkeit beim Hinzufügen von Objekten zur Sammlung prüfen, kann es zu teuer sein, sie bei der Suche nach diesen Objekten erneut zu prüfen.

  • Utilice SingleOrDefault wenn Sie sich nicht allzu sehr um die Leistung kümmern müssen und sicherstellen wollen, dass die Annahme eines einzelnen Elements für den Leser klar ist und zur Laufzeit überprüft wird.

In der Praxis verwenden Sie First / FirstOrDefault oft sogar in Fällen, in denen Sie von einem einzigen Element ausgehen, um die Leistung zu verbessern. Sie sollten dennoch bedenken, dass Single / SingleOrDefault kann die Lesbarkeit (weil sie die Annahme eines einzelnen Elements angibt) und die Stabilität (weil sie es überprüft) verbessern und es angemessen verwenden.

87voto

shalke Punkte 941

Niemand hat erwähnt, dass FirstOrDefault in SQL übersetzt TOP 1 Datensatz macht, und SingleOrDefault macht TOP 2, weil es wissen muss, ob es mehr als 1 Datensatz gibt.

40voto

Prakash Punkte 719

Für LINQ -> SQL:

SingleOrDefault

  • wird eine Abfrage wie "select * from users where userid = 1" erzeugt
  • Wählen Sie den passenden Datensatz aus. Wenn mehr als ein Datensatz gefunden wird, wird eine Ausnahme geworfen.
  • Verwenden Sie diese Option, wenn Sie Daten basierend auf einer Primär-/Einzelschlüsselspalte abrufen

FirstOrDefault

  • wird eine Abfrage wie "select top 1 * from users where userid = 1" erzeugt
  • Erste übereinstimmende Zeilen auswählen
  • Verwenden Sie diese Option, wenn Sie Daten auf der Grundlage einer nicht primären/eindeutigen Schlüsselspalte abrufen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X