2009-06-04 11 views
16

Últimamente hemos trabajado mucho con LINQ, principalmente en un sentido LINQ-to-Objects. Desafortunadamente, algunas de nuestras consultas pueden ser un poco complicadas, especialmente cuando comienzan a involucrar múltiples secuencias en combinaciones. Puede ser difícil saber exactamente lo que está pasando, cuando recibe consultas que comienzan a parecerse a:Depuración de consultas LINQ

IEnumerable<LongType> myCompanies =  relevantBusiness.Children_Companies 
      .Select(ca => ca.PR_ContractItemId) 
      .Distinct() 
      .Select(id => new ContractedItem(id)) 
      .Select(ci => ci.PR_ContractPcrId) 
      .Distinct() 
      .Select(id => new ContractedProdCompReg(id)) 
      .Select(cpcr => cpcr.PR_CompanyId) 
      .Distinct(); 

var currentNewItems = myCompanies 
       .Where(currentCompanyId => !currentLic.Children_Appointments.Select(app => app.PR_CompanyId).Any(item => item == currentCompanyId)) 
       .Select(currentId => new AppointmentStub(currentLic, currentId)) 
       .Where(currentStub=>!existingItems.Any(existing=>existing.IsMatch(currentStub))); 


Items = existingItems.Union(newItems).ToList(); 

etc, etc ...

Incluso cuando se depura, puede ser difícil saber quién está haciendo qué a quién y cuándo. A menos que llame innecesariamente a "ToList" en secuencias para obtener cosas que pueda examinar más fácilmente, ¿alguien tiene alguna buena sugerencia sobre cómo depurar LINQ "complicado"?

Respuesta

13

Parece que una consulta como esa me indica que no está haciendo un buen trabajo al elegir las estructuras de datos apropiadas, o haciendo un buen trabajo con la encapsulación y la separación de tareas. Sugeriría echarle un vistazo y romperlo.

En general, si quiero depurar una consulta LINQ que no es obviamente correcta, la dividiría en subconsultas y examinaría los resultados uno a uno en el depurador.

+2

+1 para la refacturación del LINQ mess. –

+0

cordialmente de acuerdo. Con LinqToObjects cada paso en la cadena realmente le dará un objeto para trabajar y examinar. A diferencia de LinqToSQL, donde la evaluación de expresión se retrasa hasta el final, los métodos de extensión en LinqToObjects funcionan igual que otros métodos y se evalúan inmediatamente. – tvanfosson

+1

Las consultas de LINQ to Object también utilizan la evaluación deferida. Pero puedes evaluarlos durante la depuración. –

4

No hay herramientas de compilación de las que tenga conocimiento. Lo mejor que puede hacer es dividir la consulta en varias subconsultas y evaluar estas subconsultas durante la depuración. Una buena herramienta de terceros es LINQPad.

3

This blog post tiene algunas técnicas muy prometedoras para depurar LINQ to Objects.

13

sé que mi respuesta es "un poco" tarde, pero tenía que compartir esto:

Sólo descubierto LinqPad y es increíble (por no hablar gratis).
No puedo creer que haya escrito Linq durante tanto tiempo sin conocer esta herramienta.

Por lo que entiendo, es el trabajo del autor (s?) De O'Reilly "C# 3.0 in a Nutshell" y "C# 4.0 in a Nutshell".

8

Cuando miré a mi alrededor recientemente para encontrar respuestas a la misma pregunta, encontré algunas pistas intrigantes aquí y allá, pero no hubo una narrativa cohesiva que realmente investigara la respuesta a la pregunta. Así que escribí uno y acaba de publicarse en Simple-Talk.com (LINQ Secrets Revealed: Chaining and Debugging). Es posible que deba registrarse para leer el artículo (el sitio parece estar sufriendo algunos cambios en los últimos días) así que aquí están los aspectos más destacados del artículo:

(1) En LINQPad: utilice su extraordinario método Dump(). Puede inyectar esto en uno o más puntos en una cadena LINQ para ver sus datos visualizados de una manera asombrosa, limpia y clara.

(2) En Visual Studio: Incruste instrucciones de nop en el medio de su cadena LINQ para que pueda establecer puntos de interrupción. Tenga en cuenta que la declaración de devolución debe estar en su propia línea para establecer un punto de interrupción en Visual Studio. (Gracias a el blog de Eric White Debugging LINQ Queries por este consejo.)

.Select(z => 
{return z;} 
) 

(3) En Visual Studio: Inyectar las llamadas al método de extensión de vaciado() que presento en mi artículo para permitir la tala. 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.

(4) Finalmente, (sí, estoy enamorado del método de descarga de LINQPad!) Lleve la visualización de LINQPad directamente a Visual Studio con el complemento LINQPad Visualizer de Robert Ivanc. No es una solución perfecta (todavía no hay soporte para VS2010, requiere que las clases sean serializables, algunos problemas de renderizado) pero es bastante útil.

2016.12.01 actualización

Acaba de aparecer en Simple-Talk.com es la secuela del artículo anterior: LINQ Debugging and Visualization. Este artículo proporciona una cobertura exhaustiva de la nueva capacidad de depuración LINQ de la extensión OzCode para Visual Studio 2015. OzCode finalmente hace que la depuración LINQ sea fácil y poderosa. (Y, no, hago no trabajo para OzCode :-).

+0

¡Buena técnica para conocer! – GWLlosa

+1

y ahora el visualizador es compatible tanto con vs2010 como con las clases que no son serializables. :) –

+0

¡La mejor respuesta! – menkow

2

Horse Apples!

ReSharper (que me encanta) sugirió cambio esto

foreach (BomObservation initialObservation in initialObservations) 
{ 
    if(initialObservation.IsValid() && !initialObservation.IsStationOnly) 
     mappableObservations.Add(initialObservation); 
} 

a este

initialObservations.Where(observation => observation.IsValid() && !observation.IsStationOnly).ToList(); 

Yeh es sexy y elegante, pero paso a paso a través de él y depurarlo? Simplemente no puedes hacerlo. Voy a volver a foreach para este.

También me encanta LinqPad y creo que Linq es bastante impresionante en un "anillo para gobernarlos a todos", pero en este escenario pierdo algo.

Cuestiones relacionadas