2012-09-22 13 views
15

Mam tabeli użytkowników:Znajdź rekord w dbSet użycie funkcji Znajdź bez klucza podstawowego

Users: 
+ID 
+Username 
+... 

chcę użyć myDBContext.Users.Find(Username) do fin do użytkowników. w moim obecnym kontekście nie mogę użyć jego identyfikatora.

Czy muszę użyć pełnego zapytania LINQ? na przykład

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

Próbowałem również zdefiniować nazwę użytkownika jako klucz podstawowy w moim edmx ale to spowodowało następujący błąd:

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

Odpowiedz

35

Wypróbuj za pomocą,

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

Użyj SingleOrDefault insted z Single. Jeśli użytkownik nie istnieje, wówczas błąd zostanie zgłoszony przez Single. Podczas gdy SingleOrDefault zwróci null, jeśli użytkownik nie stwierdzi inaczej, obiekt zostanie zwrócony.

Wybór pomiędzy SingleOrDefault i FirstOrDefault

można uzyskać obiekt użytkownika za pomocą SingleOrDefault i FirstOrDefault ale przy wyborze stosowanej metody rozważyć poniżej punktach.

  • Obie zwracają tylko jedną wartość z kolekcji/bazy danych, jeśli istnieje inna wartość domyślna.
  • Ale jeśli masz więcej niż jednego użytkownika o tej samej nazwie i spodziewasz się uzyskać wyjątek podczas wykonywania zapytania LINQ, użyj SingleOrDefault, ponieważ spowoduje to zgłoszenie wyjątku, jeśli jest dostępny więcej niż jeden element.
  • A jeśli nie chcesz wyjątku i/lub nie chcesz sprawdzać, czy twoja kolekcja/baza danych ma duplikację danych, po prostu chcesz uzyskać pierwszą wartość z kolekcji/bazy danych, a następnie użyj FirstOrDefault dla lepszej wydajności w porównaniu z SingleOrDefault

FirstOrDefault

  • Ogólnie FirstOrDefault lub First stosowane kiedy wymagana pojedynczą wartość (pierwszy) z kolekcji lub bazy danych.
  • W przypadku Fist/FirstOrDefault, tylko jeden wiersz jest pobierany z bazy danych, więc działa nieco lepiej niż pojedynczy/SingleOrDefault. tak mała różnica jest ledwo zauważalna, ale gdy tabela zawiera dużą liczbę kolumn i rzędów, w tym momencie zauważalna jest wydajność.

Niektóre inne uwagi

  • Jeśli username jest klucz podstawowy to myślę nie będzie dużo/ma różnicy między SingleOrDefault i FirstOrDefault wydajności jako klucz podstawowy jest indeks i wyszukiwania na kolumnie indeks będzie zawsze być szybsze niż normalna kolumna.
  • Single lub SingleOrDefault wygeneruje regularny TSQL jak "WYBIERZ ...".
  • First lub FirstOrDefault metoda generowania statment TSQL jak „SELECT TOP 1 ...”
+0

jeszcze lepiej! .. dzięki. – Mortalus

+0

Czy nie byłoby lepiej użyć 'FirstOrDefault' zamiast? Moje rozumienie metody 'SingleOrDefault' polega na tym, że przegląda ona cały * stół *, aby upewnić się, że tylko jeden rekord pasuje do warunku. Być może nie zależy to od PO. – Crono

+1

@Crono Tak, masz rację dla FirstOrDefault, jeśli weźmiemy pod uwagę jego wydajność w porównaniu z SingleOrDefault. Ale tutaj myślę, że w zależności od oczekiwanego rezultatu powinniśmy dokonać wyboru między tymi dwoma metodami. Jeśli chcesz tylko jeden wynik i spodziewasz się wyjątku, jeśli istnieje więcej niż jedna sekwencja tego samego, użyj SinleOrDefault, w przeciwnym razie użyj FirstOrDefault. Zaktualizuję swoją odpowiedź w tym kontekście. –

3

Znalazłem to:

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

Tak to jest w porządku, ale należy przyjąć to jako odpowiedź, ponieważ jest to rozwiązanie problemu. –

+0

Dobrze, że mogę tylko zaakceptować to za dwa dni, więc poczekam .. tnx – Mortalus

+0

@Mortalus znaleźć moją odpowiedź, jeśli to pomoże na twoje pytanie. Właśnie zmieniłem Single na SingleOrDefault. –

Powiązane problemy