2010-02-21 6 views
5

¿Cómo puedo especificar condiciones en los predicados Where en LINQ sin obtener excepciones de referencia nula? Por ejemplo, si q es IQueryable cómo puedo me gusta:Dónde Predica en LINQ

Expression<Func<ProductEntity,bool>> predicate = p => !search.CategoryId.HasValue || (search.CategoryId.HasValue && search.CategoryId == p.CategoryId); 

var q2 = q.Where(predicate); 

Aquí search es un objeto que contiene posibles condiciones de búsqueda que pueden o no se pueden establecer como search.CategoryId no esté definida, pero si es Quiero obtener los productos que están configurados por esa condición.

Cuando hago esto obtengo excepciones de referencia nulas.

Respuesta

7

Puede usar null-coalescing operator?? para reemplazar un posible valor nulo con un valor predeterminado. Los siguientes conjuntos intentan hacer coincidir la búsqueda. Categoría si existe o simplemente crea una expresión "siempre verdadera". Esto será optimizado por cualquier buen proveedor de consultas Linq (por ejemplo, LinqToSql).

Expression<Func<ProductEntity,bool>> predicate = (p => (search.CategoryId ?? p.CategoryId) == p.CategoryId)); 

var q2 = q.Where(predicate); 

Otra posibilidad sería la de componer dinámicamente un predicado de la consulta utilizando PredicateBuilder. Esa es la manera que lo hago para las búsquedas con un patrón similar al que utilice:

var predicate = PredicateBuilder.True<Order>(); 

if (search.OrderId)) 
{ 
    predicate = predicate.And(a => SqlMethods.Like(a.OrderID, search.OderID); 
} 
// ... 
var results = q.Where(predicate); 
3

Analicemos la línea:

Expression<Func<ProductEntity,bool> predicate = p => !search.CategoryId.HasValue 
     || (search.CategoryId.HasValue && search.CategoryId == p.CategoryId) 
var q2 = q.Where(predicate); 

Entonces, ¿cuántas maneras se puede obtener null problemas?

  • search (su "capturado" variable) podría ser null
  • p podría ser nula, es decir, hay un null en la lista
  • usted ha manejado el caso de search.CategoryId siendo null (Nullable<T>)
  • pero tal vez p.CategoryId (la categoría en un registro en la lista) es null (Nullable<T>) - howe ver, no estoy seguro de que esto causaría un NullReferenceException
  • q (la lista/fuente) podría ser null

Por lo tanto: de 5 opciones que hemos eliminado 1; mira los otros 4? Hay también existe la posibilidad definitiva de que el problema esté causado por algo invisible que no se muestra en el código; por ejemplo, el get podrían ser:

public int? CategoryId { 
    get {return innerObject.CategoryId;} 
} 

y innerObject podría ser null; si eliminas las otras 4 (bastante fácil de hacer), mira esto como último recurso.