2012-09-22 5 views
15

Ich habe eine Benutzer-Tabelle:Finden Sie einen Datensatz in dbSet mit Suche ohne Primärschlüssel

Users: 
+ID 
+Username 
+... 

Ich möchte myDBContext.Users.Find(Username) verwenden, um einen Benutzer fin. In meinem aktuellen Kontext kann ich seine ID nicht verwenden.

Muss ich eine vollständige LINQ-Abfrage verwenden? z.B.

var user = from users in myDBContext.Users.Find(Username) 
      where users.Username == username 
      select users 

Ich habe auch die Benutzername als Primärschlüssel in meiner edmx zu definieren versucht, aber dass in den folgenden Fehlern in Folge:

Properties referred by the Principal Role User must be exactly identical to the key of the EntityType CamelotShiftManagementModel.User referred to by the Principal Role in the relationship constraint for Relationship CamelotShiftManagementModel.AssociationUserFK1. Make sure all the key properties are specified in the Principal Role. C:\Code\CamelotShiftManagement\CamelotShiftManagement\Models\CamelotDB.edmx 278 11 CamelotShiftManagement

Antwort

35

Versuchen Sie mit,

User myUser = myDBContext.Users.SingleOrDefault(user => user.Username == username); 

Verwenden Sie SingleOrDefault anstelle von Single. Wenn der Benutzer nicht existiert, wird Single einen Fehler auslösen. Während SingleOrDefault wird null zurückgeben, wenn Benutzer nicht anders User Objekt wird zurückgegeben werden.

Auswahl zwischen SingleOrDefault und FirstOrDefault

Sie das Benutzerobjekt unter Verwendung SingleOrDefault und FirstOrDefault aber während der Auswahl, welche Methode unten Punkte beachten verwenden zu können.

  • Beide geben nur einen Wert aus Sammlung/Datenbank zurück, wenn der Standardwert andernfalls existiert.
  • Wenn Sie jedoch mehr als einen Benutzer mit demselben Namen haben und bei der Ausführung der LINQ-Abfrage eine Ausnahme erwarten, verwenden Sie SingleOrDefault, da eine Ausnahme ausgelöst wird, wenn mehr als ein Element verfügbar ist.
  • Und wenn Sie keine Ausnahme möchten und/oder nicht möchten, dass Ihre Sammlung/Datenbank doppelte Daten enthält, möchten Sie nur den ersten Wert aus der Sammlung/Datenbank verwenden und dann FirstOrDefault für eine bessere Leistung verwenden, vergleichen Sie mit SingleOrDefault

FirstOrDefault

  • Allgemeinen FirstOrDefault oder First verwendet, wenn wir einzelne Wert (erste) aus der Sammlung oder Datenbank erforderlich.
  • Im Fall von Fist/FirstOrDefault wird nur eine Zeile aus der Datenbank abgerufen, sodass sie etwas besser als single/SingleOrDefault funktioniert. so ein kleiner Unterschied ist kaum wahrnehmbar, aber wenn die Tabelle eine große Anzahl von Spalten und Zeilen enthält, ist zu dieser Zeit die Leistung bemerkbar.

Einige andere Bemerkungen

  • Wenn username Primärschlüssel ist, werde ich denke, dann gibt es keine viel sein/kein Unterschied zwischen SingleOrDefault und FirstOrDefault Leistung als Primärschlüssel auf Indexspalte Index und die Suche wird immer Sei schneller als normale Spalte.
  • Single oder SingleOrDefault generiert eine reguläre TSQL wie "SELECT ...".
  • Die First oder FirstOrDefault Methode wird die TSQL statment wie „SELECT TOP 1 ...“
+0

noch besser! .. Vielen Dank. – Mortalus

+0

Wäre es nicht besser, stattdessen 'FirstOrDefault' zu verwenden? Mein Verständnis der 'SingleOrDefault' Methode ist, dass es die * ganze * Tabelle durchsuchen wird, um sicherzustellen, dass nur ein Datensatz der Bedingung entspricht. Es kann nicht sein, was das OP will. – Crono

+1

@Crono Ja, Sie haben Recht für FirstOrDefault, wenn wir die Leistung im Vergleich zu SingleOrDefault betrachten. Aber hier denke ich, abhängig vom erwarteten Ergebnis sollten wir eine Auswahl zwischen diesen beiden Methoden treffen. Wenn Sie nur ein einzelnes Ergebnis wünschen und eine Ausnahme erwarten, wenn mehrere Sequenzen vorhanden sind, verwenden Sie SinleOrDefault, andernfalls FirstOrDefault. Ich werde meine Antwort mit diesem Kontext aktualisieren. –

3

ich gefunden habe es:

User myUser = myDBContext.Users.Single(user => user.Username == i_Username); 
+0

Ja, es ist in Ordnung, generieren, aber Sie sollten es als Antwort akzeptieren, da sie die Lösung für Ihr Problem. –

+0

Nun, es sagt mir, ich kann es nur in zwei Tagen akzeptieren, also werde ich warten .. tnx – Mortalus

+0

@Mortalus finden Sie meine Antwort, wenn es um Ihre Frage zu helfen. Ich habe gerade Single zu SingleOrDefault geändert. –

Verwandte Themen