2009-11-30 20 views
6

estoy usando la siguiente declaración con la intención de conseguir todos los objetos de máquina de la colección MachineList (tipo IEnumerable) que tienen un MachineStatus de i. La colección MachineList no siempre contendrá máquinas con un estado de i.una colección vacía cuando LINQ donde no devuelve nada

En momentos en que ninguna máquina tiene un MachineStatus de i Me gustaría devolver una colección vacía. Mi llamada al ActiveMachines (que se usa primero) funciona pero InactiveMachines no.

public IEnumerable<Machine> ActiveMachines 
{ 
    get 
    { 
     return Customer.MachineList 
      .Where(m => m.MachineStatus == "a"); 
    } 
} 

public IEnumerable<Machine> InactiveMachines 
{ 
    get 
    { 
     return Customer.MachineList 
      .Where(m => m.MachineStatus == "i"); 
    } 
} 

Editar

Un examen más detallado, parece que cualquier enumeración de MachineList hará que las enumeraciones subsecuentes de MachineList a lanzar una exeception: Object reference not set to an instance of an object. Por lo tanto, no importa si se realiza una llamada a ActiveMachines o InactiveMachines ya que es un problema con la colección MachineList. Esto es especialmente preocupante porque puedo interrumpir las llamadas al MachineList simplemente al enumerarlo en un reloj antes de que se llame en el código. En su nivel más bajo, MachineList implementa NHibernate.IQuery y se devuelve como IEnumerable. ¿Qué está causando que MachineList pierda su contenido después de una enumeración inicial?

+0

No, nada especial sucede en la enumeración; sería interesante ver qué elementos "inactivos" están en el depurador. También me pregunto si (por ejemplo) 'MachineStatus' es una propiedad de fachada que arroja una excepción, es decir,' cadena pública MachineStatus {get {return someInnerField.Status;}} 'y' someInnerField' es 'null'. –

+0

El problema real es que está enumerando un 'IEnumerable' varias veces. El contrato implícito que usted acepta cuando consume un 'IEnumerable' es enumerarlo solo una vez. Entonces, la respuesta real no es que su compañero de trabajo cambie su código para permitir la enumeración múltiple, sino que haga 'Customer.MachineList.ToList()' en algún momento y luego solo use la lista resultante después de eso (o, obtenga un nuevo 'IEnumerable' de nuevo). Puedes hacer una evaluación perezosa; puede almacenarlo en caché, pero no lo enumere dos veces. También puede exponer un 'IQueryable' y llamarlo varias veces también. – ErikE

Respuesta

7

Where devuelve una secuencia vacía si no hay coincidencias; esta es una secuencia perfectamente válida (no nula). La única forma en que obtendría un nulo es llamando a FirstOrDefault o SingleOrDefault.

¿Estás seguro de que el error está donde crees que está?

int?[] nums = { 1, 3, 5 }; 
var qry = nums.Where(i => i % 2 == 0); 
Console.WriteLine(qry == null); // false 
Console.WriteLine(qry.Count()); // 0 
var list = qry.ToList(); 
Console.WriteLine(list.Count); // 0 
var first = qry.FirstOrDefault(); 
Console.WriteLine(first == null); // true 
+0

Eso es lo que pensé. Modifiqué mi pregunta para reflejar una modificación que arroja el mismo error. – ahsteele

+0

Agregué información adicional a mi pregunta que podría arrojar algo de luz sobre lo que está sucediendo. Dicho esto, creo que podría estar bordeando la necesidad de abrir un nuevo hilo. – ahsteele

+0

El error tenía que ver con la forma en que se estaba construyendo MachineList. Había estado consumiendo este método de otro desarrollador y no había comprobado la forma en que se estaba creando. Gracias por apuntarme en la dirección correcta al preguntar si estaba seguro de que estaba buscando en el lugar correcto. – ahsteele

4

Por defecto, Enumerable.Where ya hace devolver un vacío IEnumerable<T>, no nulo. Si está viendo "Referencia de objeto no establecida en una instancia de un objeto". excepciones, lo más probable es que el problema sea otra cosa.

¿Es MachineList null, quizás? Si no lo había creado, se obtendría esa excepción en su llamada a .Where(...)

+0

Gracias por apuntarme en la dirección correcta al preguntar si estaba seguro de que estaba buscando en el lugar correcto. – ahsteele

2

Además, si desea volver explícitamente una colección vacía, esto puede ayudar ...

Enumerable.Empty<Machine>(); 
Cuestiones relacionadas