2008-09-23 7 views
38

Tengo una declaración de LINQ a objetosCómo depurar una declaración de LINQ

var confirm = from l in lines.Lines 
where (l.LineNumber == startline.LineNumber) || (l.LineNumber == endline.LineNumber) 
select l; 

El objeto confirmar devuelve un 'objeto nulo o no una referencia' en al System.Linq.Enumerable.WhereListIterator`1.MoveNext()

Si el resultado de la consulta estaba vacío, simplemente devolvería un enumerador vacío. Sé a ciencia cierta que no hay objetos nulos en la declaración. ¿Es posible recorrer la declaración LINQ para ver dónde se está cayendo?

EDITAR cuando dije Sé que es un hecho que hay objetos no nula resulta que yo estaba mintiendo: [, pero la pregunta sigue siendo, sin embargo estoy Asumiendo que la respuesta será 'no se puede realmente'

LINQPad es una buena idea, que lo utilizó para enseñar a mí mismo LINQ, pero puede empezar a ver de nuevo como una depuración/tala y quema herramienta de estilo

+0

¿Cuál fue la respuesta? –

+3

42. En realidad, si lees mi edición, es que tuve una referencia nula, a pesar de mi seguridad de lo contrario – johnc

Respuesta

27

no estoy seguro si es posible depurar de VS, pero creo que LINQPad es bastante útil. Te permitirá volcar los resultados de cada parte de la consulta LINQ.

+6

Al igual que el otro lado de la almohada. – Dested

3

Compruebe el seguimiento de la pila de excepciones y vea el último bit del código que se ejecutó.

+0

Así es como llegué a System.Linq.Enumerable.WhereListIterator'1.MoveNext() – johnc

+0

¿Cuál es la última línea de * su * código que se ejecutó? WhereListIterator no es su código (es una API LINQ). –

3

Desde el aspecto del error, le sugiero que eche un vistazo a line.Lines y asegúrese de que su enumerador esté implementado correctamente. Creo que está devolviendo un nulo cuando no debería.

Ah, y simplemente asegúrese de que la línea y la línea.Los objetos de línea no son nulos o devuelven nulos también.

14

Debería poder establecer un punto de interrupción en la expresión en la cláusula where de su instrucción LINQ.

En este ejemplo, poner el cursor en cualquier lugar en la siguiente sección de código:

(l.LineNumber == startline.LineNumber) || (l.LineNumber == endline.LineNumber) 

A continuación, pulse F9 o utiliza el menú contextual del menú o para añadir el punto de interrupción.

Cuando se establece correctamente, solo el código anterior debe tener el formato de punto de interrupción en el editor en lugar de toda la instrucción LINQ. También puede mirar en la ventana de puntos de interrupción para ver.

Si lo ha configurado correctamente, se detendrá cada vez en la función que implementa la parte de arriba de la consulta.

+1

Esta puede no ser la respuesta que el OP estaba buscando, pero me ayudó mucho.Pensé que Visual Studio no podía depurar expresiones lambda, principalmente porque cuando insertaba los puntos de interrupción (con el cursor en la columna incorrecta) estaba pintando toda la línea, no solo la lambda que quería depurar, sino también porque la ventana de Quick Watch no puede evaluar expresiones lambda. – ygormutti

+0

Para aclarar, el depurador ingresará la consulta linq siguiente * la primera referencia * a la variable que contiene la consulta linq –

29

Sí, es posible pausar la ejecución a mitad de una consulta de linq.

Convierta su linq al estilo de consulta utilizando expresiones lambda e inserte una instrucción Select que se devuelva en algún lugar después del punto en el linq que desea depurar. Un código de muestra lo hará más claro -

 var query = dataset.Tables[0].AsEnumerable() 
      .Where (i=> i.Field<string>("Project").Contains("070932.01")) 
//   .Select(i => 
//   {return i;} 
//   ) 
      .Select (i=>i.Field<string>("City")); 

A continuación, elimine el comentario de las líneas comentadas. Asegúrese de que {return i;} esté en su propia línea e inserte un punto de depuración allí. Puede poner esto seleccionar en cualquier punto de su larga y complicada consulta de linq.

14

Escribí un artículo exhaustivo sobre esta misma pregunta publicada en Simple-Talk.com (LINQ Secrets Revealed: Chaining and Debugging) en 2010:

hablo de LINQPad (como se mencionó anteriormente por OwenP) como una gran herramienta externa a Visual Studio. Presta especial atención a su extraordinario método de volcado(). Puede inyectar esto en uno o más puntos en una cadena LINQ para ver sus datos visualizados de una manera asombrosamente limpia y clara. Aunque es muy útil, LINQPad es externo a Visual Studio. Así que también presentan varias técnicas disponibles para su uso dentro Visual Studio porque a veces es simplemente no es práctico para migrar un trozo de código a LINQPad:

(1) Inyectar llama al método de extensión de vaciado() que presento en mi artículo para permitir el registro. Empecé con el método Watch() de Bart De Smet en su artículo informativo LINQ to Objects – Debugging y agregué algunas etiquetas y coloraciones para mejorar la visualización, aunque aún es insignificante en comparación con la salida de Volcado de LINQPad.

(2) Trae la visualización de LINQPad directamente a Visual Studio con el complemento LINQPad Visualizer de Robert Ivanc. No estoy seguro si fue a través de mi insistencia :-), pero los inconvenientes de la pareja presente cuando estaba escribiendo mi artículo ahora han sido abordados admirablemente en el último lanzamiento. Tiene compatibilidad total con VS2010 y le permite examinar cualquier objeto que desee al depurar.

(3) Incruste declaraciones de nop en el medio de su cadena LINQ para que pueda establecer puntos de interrupción, como se describió anteriormente por Amazing Pete.

2016.12.01 actualización

Y acabo de escribir la secuela del artículo anterior, titulado simplemente LINQ Debugging and Visualization, lo que revela que la verdadera capacidad de depuración LINQ finalmente ha llegado en Visual Studio 2015, con la sobre-a-ser - nueva característica lanzada en OzCode. La respuesta de @Dror a esta pregunta muestra un pequeño vistazo, pero los animo a leer mi nuevo artículo para obtener un "cómo hacerlo" en profundidad. (Y lo hago no trabajo para OzCode. :-)

3

Es posible entrar dentro de la expresión LINQ sin establecer ningún punto de interrupción temporal. Es necesario para entrar en la función que evalúa la expresión LINQ, por ejemplo:

var confirm = from l in lines.Lines 
       where (l.LineNumber == startline.LineNumber) 
        || (l.LineNumber == endline.LineNumber) 
       select l; 

confirm.ToArray(); // Press F11 ("Step into") when you reach this statement 

foreach(var o in q) // Press F11 when "in" keyword is highlighted as "next statement" 
    // ... 
+0

Funciona incluso con '.ToList()' – xleon

+1

Esta debería ser la respuesta aceptada. –

3

[Descargo de responsabilidad: yo trabajo en OzCode]

El problema con LINQ es que es difícil imposible de depuración - incluso cuando se trata de consultas simples, un desarrollador se ve obligado a refactorizar su consulta a un grupo de bucles foreach o utilizar el registro. LINQ depuración es compatible con una versión que pronto será lanzado a de OzCode (currently available as an Early Access Preview) y ayuda a los desarrolladores de perforar en su código LINQ así y establecer claramente los difíciles de capturar las excepciones dentro consultas

Esto es lo que la consulta parezca en OzCode: Debugging LINQ exception

Cuestiones relacionadas