2013-08-06 12 views
6

Rozważmy tabelę z 2 kolumnami: ID (int) and Role (string). Oba są zerowe.Zapytanie LINQ-do-SQL nie zwraca wiersza, gdy klauzula where porównuje wartość NULL

Teraz zakładamy, że dane w dwóch kolumnach jest:

ID  Role 
--  ---- 
1  NULL 
2  Admin 

Kwerenda wygląda następująco:

List<types> t1 = (
    from a in datacontext.RoleTable 
    where a.Role != "Admin" 
    select a 
).ToList(); 

Myślałem powyższe zapytanie należy powrocie pierwszy rekord z tabeli jako jego kolumna Role nie jest równa "Admin", ale zapytanie zwraca pustą listę.

Teraz gdy używam tej kwerendy:

List<types> t2 = (
    from a in datacontext.RoleType 
    where a.Role != "Admin" && a.Role == DBNull.Value.ToString() 
    select a 
).ToList(); 

dostaję poprawną odpowiedź.

Czy ktoś może mi powiedzieć, dlaczego pierwsze zapytanie nie działa.

FYI: Jeśli kolumna roli w pierwszym wierszu tabeli zostanie zmieniona na User zamiast NULL, pierwsze zapytanie działa poprawnie.

Używam SQL Express i LINQ do SQL.

+0

Czy próbowałeś '.equals()'? –

+0

Nie, nie o to chodzi, chcę wiedzieć, dlaczego pierwsze zapytanie nie działa zgodnie z oczekiwaniami. –

Odpowiedz

10

pierwsze zapytanie nie zachowuje się zgodnie z oczekiwaniami, ponieważ jest w języku SQL, która jest równoważna następującej:

select * from RoleTable where Role != 'Admin' 

Teraz w SQL NULL != 'Admin' jest nieTRUE (ani nie jest FALSE - jest niezdefiniowany).
Jest to jeden z wielu przypadków, w których abstrakcja dostarczana przez LINQ do SQL jest nieszczelna i nadal trzeba znać SQL.

BTW: Twoje drugie zapytanie również jest nieprawidłowe, zostanie wybrane tylko te wiersze, które są null. Nie wybrałby wiersza z rolą 'User'.

Prawidłowa kwerenda będzie wyglądać następująco:

List<types> t2 = 
    (from a in datacontext.RoleTable 
    where a.Role != "Admin" || a.Role == null 
    select a).ToList(); 
+0

Czysta ciekawość - czym jest "NULL! =" Admin'' w SQL? Na pewno nie "fałsz"? – Andrei

+5

@Andrei: Jest niezdefiniowany. To nie jest ani prawdziwe, ani fałszywe. –

+0

FYI: Drugie zapytanie zwraca pierwszy rekord, ponieważ nie jest równe "Admin" i jest równe dbnull –

Powiązane problemy