2013-08-06 4 views
6

Consente di considerare una tabella con 2 colonne: ID (int) e Ruolo (stringa). Entrambi sono annullabili.Query LINQ-to-SQL che non restituisce riga quando la clausola where viene confrontata con il valore NULL

Ora supponiamo che i dati nelle due colonne:

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

La query è simile al seguente:

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

ho pensato la domanda di cui sopra dovrebbe essere tornando il primo record della tabella come la sua colonna Role non è uguale a "Admin" ma la query restituisce una lista vuota.

Ora, quando ho utilizzare questa query:

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

ottengo la risposta corretta.

Qualcuno può dirmi perché la prima query non funziona, per favore.

FYI: se la colonna Ruolo nella prima riga della tabella viene modificata in User anziché NULL, la prima query funziona correttamente.

Sto usando SQL Express e LINQ a SQL.

+0

Hai provato '.equals()'? –

+0

Non è questo il punto che voglio sapere perché la prima query non si comporta come previsto. –

risposta

10

La prima query non si comporta come previsto, perché si traduce in SQL che è equivalente al seguente:

select * from RoleTable where Role != 'Admin' 

Ora, in SQL NULL != 'Admin' è nonTRUE (né è FALSE - non è definito).
Questo è uno dei molti casi in cui l'astrazione fornita da LINQ a SQL non presenta perdite e occorre ancora conoscere SQL.

BTW: Anche la seconda query non è corretta, selezionerà solo le righe che sono null. Non selezionerebbe una riga con il ruolo 'User'.

La query corretta sarebbe simile a questa:

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

Pura curiosità - che cosa è 'NULL! = 'Admin'' in SQL? Certamente non 'falso'? – Andrei

+5

@Andrei: non è definito. Non è né vero né falso. –

+0

FYI: La seconda query restituisce il primo record poiché non è uguale a "Admin" ed è uguale a dbnull –