2011-11-27 12 views
12

Aunque la ejecución del siguiente LINQ, me sale esta excepción:LINQ: excepción como "secuencia no contiene elementos"

"secuencia no contiene elementos"

código

LINQ:

newGradeRow[rowCnt + 1 + "Grade " + ExamName] = 
     objDataSet.Tables[1].Rows.Cast<DataRow>() 
     .Where(p => Convert.ToDecimal(p["EMG_MARKS_ABOVE"]) <= extSubMarks 
     && extSubMarks <= Convert.ToDecimal(p["EMG_MARKS_BELOW"])) 
     .Select(p => Convert.ToString(p["EMG_GRADE_NAME"])) 
     .First(); 

¿Alguien me puede ayudar en esto?

+3

La excepción es clara: una de las listas con las que está trabajando está vacía y no devuelve ningún resultado. – Oded

+2

como mencioné en la pregunta durante la ejecución, recibo una excepción ya que "La secuencia no contiene elementos". ¿Puedes decirme por qué recibo esa excepción o qué está mal en el código? soy nuevo en .net. –

+2

Creo que su colección no tiene artículos. ¿Qué cree que debería hacer? Esta pregunta es un ejercicio de pensamiento básico. – Amy

Respuesta

0

objDataSet.Tables[1] está vacío?

¿Quizás los datos están en objDataSet.Tables[0]?

De cualquier manera, se puede probar con objDataSet.Tables.Count() > 0

Puede hacer lo mismo para Filas: objDataSet.Tables[1].Rows.Count() > 0

+2

O ningún elemento pasa el filtro 'Donde'. La excepción se genera con 'Primero' cuando se le da una lista vacía. –

+0

oh sí. Gracias. –

39

La excepción en la llamada First método si la secuencia está vacía, ya que se afirma en el documentation . En este caso, es mejor utilizar el método FirstOrDefault; devolverá el valor predeterminado (en el caso específico null) y no se lanzará ninguna excepción.

1

Debe tener esto en cuenta que: Lo que Linq Expresión/consulta no contiene ningún registro, entonces no puede usar Single() y First().

On the place Single() in your Lambda expression use FirstOrDefault() 
2

Es difícil decir cuál secuencia no tiene elementos cuando tiene tantos ensartados en la misma línea de código. Intenta dividir tu código en varias líneas y luego depurarlo. Esto lo hará más legible también.

var myVariable = objDataSet.Tables[1]; 
var myEntity = myVariable.Rows.Cast<DataRow>().Where(
    p => Convert.ToDecimal(p["EMG_MARKS_ABOVE"]) <= extSubMarks 
    && extSubMarks <= Convert.ToDecimal(p["EMG_MARKS_BELOW"])) 
    .Select(p => Convert.ToString(p["EMG_GRADE_NAME"])).FirstOrDefault(); 

Si el problema está en algún lugar en su expresión Lambda, es posible que desee para romperlo a cabo en un bucle foreach (por el simple hecho de depuración & tener acceso a los datos dentro de la ventana inmediata de VS).

+1

Has cambiado la última llamada a 'FirstOrDefault()' que eliminará la excepción pero no has mencionado eso que es un poco extraño. –

+0

Mi error. Prefiero usar el método de extensión FirstOrDefault() sobre First() para un mejor manejo de excepciones. Luego puede verificar nulos después antes de continuar. –

6

Comience por separarlo. Su código actual no ofrece control para un depurador.

var r1 = objDataSet.Tables[1].Rows; 
var r2 = r1.Cast<DataRow>(); 
System.Diagnostics.Debug.Print("r2: {0}", r2.Count()); 
var r3 = r2.Where(p => Convert.ToDecimal(p["EMG_MARKS_ABOVE"]) <= extSubMarks 
      && extSubMarks <= Convert.ToDecimal(p["EMG_MARKS_BELOW"])); 
System.Diagnostics.Debug.Print("r3: {0}", r3.Count()); 
var r4 = r3.Select(p => Convert.ToString(p["EMG_GRADE_NAME"])); 
var r5 = r4.First(); 

newGradeRow[rowCnt + 1 + "Grade " + ExamName] = r5; 
+0

Si bien el código es un poco complicado, es bastante claro que lo único que arrojaría esa excepción es la llamada a First() que requiere 1 o más elementos. –

+0

@BenRobinson, de acuerdo, pero ¿está vacío antes o después de 'Where()'? Me gustaría saber. –

+3

Bastante, pero le sugiero que mencione que es la llamada a 'First()' lo que arroja y explica la diferencia entre 'First()' y 'FirstOrDefault()' –

Cuestiones relacionadas