2012-02-14 6 views
6

Parece una pregunta estúpida, pero simplemente no la entiendo. Mi entidad:Expresión de Linq con nullable

public class Page 
{ 
    public int Id { get; set; } 
    //... 
    public int? ParentId { get; set; } 
} 

En el regulador:

db.Pages.First(x => x.ParentId == null); 

funciona como se espera (devuelve algún elemento). Pero :

int? test = null; 
db.Pages.First(x => x.ParentId == test); 

Lanza Sequence contains no elements

¿Qué me he perdido?

+1

¿Estás utilizando linq-to-entities? Esto no tiene nada específico que ver con asp.net-mvc? – gideon

Respuesta

10

Creo que hay una rareza alrededor de los nulos con algunos proveedores de LINQ. Proveedores:

var query = db.Pages.First(x => (test != null && x.ParentId == test) || 
           (test == null && x.ParentId == null)); 

alternativa, puede utilizar diferentes consultas para las distintas situaciones:

var query = test == null ? db.Pages.First(x => x.ParentId == null) 
         : db.Pages.First(x => x.ParentId == test); 

Básicamente esto se debe a que SQL trata NULL como desigual a sí mismo, así:

WHERE X = Y 

se siguen sin si tanto X como Y son valores nulos. El uso de la pieza == null (con literal nulo) fuerza una conversión a ISNULL o cualquiera que sea el equivalente SQL.

Acepto que es un problema, y ​​que otra persona pueda tener una mejor solución, pero esto puede ayudarlo a ponerse en marcha.

+2

_formación más adecuada_ Mover a un proveedor LINQ decente, ling NH ... – gdoron

1

Prueba esto (modificado de acuerdo con el comentario de gdoron Ahora es exactamente lo que Gideon publicado, así que por favor acepte su vez de la mina.):

int? test = null; 
if(test.HasValue) { 
    db.Pages.First(x => x.ParentId == test.Value); 
} else { 
    db.Pages.First(x => x.ParentId == null); 
} 
+2

No funciona. 'Valor: el valor del objeto Nullable actual (Of T) si la propiedad HasValue es verdadera. ==> Se lanza una excepción si la propiedad HasValue es falsa. <== ' – gdoron

+0

Sí, gracias por la pista. –

+0

thx para esta solución, pero solo quería entender esa rareza de LINQ – Wonder

2

Se podría hacer algo así como una solución:

int? test = null; 
if(test.HasValue) { 
db.Pages.First(x => x.ParentId == test.Value); 
} else { 
db.Pages.First(x => x.ParentId == null); 
} 

Asumo desde int? es en realidad un proveedor Nullable<int> nuestros LINQ a las entidades no está comparando cosas bien.

Cuestiones relacionadas