2010-03-23 18 views
14

El código siguiente funciona a menos que p.School.SchoolName resulte nulo, en cuyo caso da como resultado una NullReferenceException.linq where cláusula y recuento dan como resultado excepción nula

if (ExistingUsers.Where(p => p.StudentID == item.StaffID && 
         p.School.SchoolName == item.SchoolID).Count() > 0) 
{ 
    // Do stuff. 
} 

ExistingUsers es una lista de los usuarios:

public List<User> ExistingUsers; 

Aquí está la parte correspondiente de la StackTrace:

System.NullReferenceException: referencia a objeto no establecida como instancia de un objeto .

en System.Linq.Enumerable.WhereListIterator 1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable
1 fuente)

¿Cómo debo manejar esta cláusula where?

Muchas gracias de antemano.

+5

¿Estás seguro de que es SchoolName nulo y no p.School? –

+6

Como nota general, en lugar de hacer IEnumerable.Count (predicate)> 0, use IEnumerable.Any (predicate). Esto terminará la ejecución de la primera coincidencia que se encuentre, lo que podría generar una gran aceleración. – recursive

+0

@Anthony: muchas gracias, creo que tienes razón acerca de que es p.School que es nulo. – IntrepidDude

Respuesta

24

Sospecho que p.School es nulo, no SchoolName. Simplemente agregue un cheque nulo antes de acceder al SchoolName. Además, use Any() para verificar si hay resultados en lugar de Count() > 0 a menos que realmente necesite el conteo. Esto funciona mejor ya que no todos los elementos se repiten si existen.

var result = ExistingUsers.Where(p => p.StudentID == item.StaffID 
          && p.School != null 
          && p.School.SchoolName == item.SchoolID) 
         .Any(); 

if (result) { /* do something */ } 
+0

Esto funcionó como un encanto. Muchas gracias, ¡lo he aprendido! – IntrepidDude

0

En el caso en que desee obtener el valor nulo (todos los estudiantes, con escuela o no) Use left join.

Hay un buen ejemplo en MSDN

0

Si no recuerdo mal (no en mi desarrollador de PC en este momento y no se puede verificar con reflector), utilizando los resultados == operador en llamar a la instance implementationstring.Equals(string), no el implementación estática String.Equals(string, string).

Suponiendo que su problema se debe a SchoolName siendo nula, como usted sugiere, intente esto:

if (ExistingUsers.Where(
    p => p.StudentID == item.StaffID 
    && String.Equals(p.School.SchoolName, item.SchoolID)).Count() > 0) 
{ 
    // Do stuff. 
} 

Por supuesto, los comentarios de otras respuestas cuentan así:

  • Usando Any() en lugar de Count() > 0 generalmente tendrá un mejor rendimiento
  • Si p.School es el nulo, necesitará un cheque adicional

Espero que esto ayude.

1

Para todas las columnas que aceptan valores de base de datos, debemos agregar una comprobación nula o hacer una comparación simple a == b en lugar de a.ToLower() == b.ToLower() o operaciones de cadenas similares.
Mi observación es la siguiente:
Dado que se repiten en Enumerable of LINQ Query para comparar con la cadena/valor de entrada, cualquier valor nulo (de la columna de la base de datos) y operaciones generarán excepción, pero Enumerable se convierte en NULL, aunque query No es nulo.

Cuestiones relacionadas