tags:

views:

625

answers:

5

We've been doing a lot of work with LINQ lately, mainly in a LINQ-to-Objects sense. Unfortunately, some of our queries can be a little complicated, especially when they start to involve multiple sequences in combinations. It can be hard to tell exactly what's going on, when you get queries that start to look like:

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...

Even when you debug, it can be difficult to tell who's doing what to who and when. Short of gratuitously calling "ToList" on sequences to get things I can examine more easily, does anyone have any good suggestions for how to debug "complicated" LINQ?

+1  A: 

Try this stackoverflow question: http://stackoverflow.com/questions/118341/how-to-debug-a-linq-statement

John JJ Curtis
Unfortunately, that addon is about Linq-To-SQL, and we're mostly having trouble with Linq-To-Objects.
GWLlosa
My bad, sorry about that. I did find another stackoverflow question about this here: http://stackoverflow.com/questions/118341/how-to-debug-a-linq-statement
John JJ Curtis
Thanks, some of those answers were pretty helpful.
GWLlosa
+3  A: 

There are no build in tools I am aware of. The best you can do is splitting the query in multiple subqueries and evaluate these subqueries while debuging. A good 3rd party tool is LINQPad.

Daniel Brückner
+8  A: 

A query like that seems to indicate to me that you're not doing a good job choosing appropriate data structures, or doing a good job with encapsulation and separation of tasks. I'd suggest taking a look at it and breaking it up.

In general, though, if I want to debug a LINQ query that isn't obviously correct, I'd break it up into subqueries and examine the results one-at-a-time in the debugger.

mquander
+1 for refactoring the LINQ mess.
Daniel Brückner
Heartily agree. With LinqToObjects each step in the chain will actually give you an object to work with and examine. Unlike LinqToSQL where the expression evaluation is delayed until the end, the extension methods in LinqToObjects work just like other methods and evaluate immediately.
tvanfosson
LINQ to Object queries use defered evaluation, too. But you can evaluate them while debuging.
Daniel Brückner
Is there a way to get the object to 'evaluate now'? Like if I have an IEnumerable<T> that's deferred, is there some '.Go()' function I can call on it in the debugger to check its current state?
GWLlosa
As for the object structure, the best phrase to describe it is "Legacy Code out of my control".
GWLlosa
GW: In the Visual Studio 2008 debugger, if execution is stopped with an IEnumerable in scope, you can mouseover the reference and go to "Results" in the menu to evaluate the enumeration. Alternately, you can just call ToArray().
mquander
LINQ can be an open invitation to pernicious evil - to abandon Separation of Concerns and encapsulation, to increase coupling. etc. etc. Resist overscoping the way you apply it.
le dorfier
+2  A: 

This blog post has some very promising techniques for debugging LINQ to Objects.

Joel Mueller
+2  A: 

I know my answer is a "bit" late, but I had to share this:

Just discovered LinqPad and it's AMAZING (not to mention free).
Can't believe I've written Linq for so long without knowing about this tool.

As far as I understand, it's the work of the author(s?) of O'Reilly's "C# 3.0 in a Nutshell" and "C# 4.0 in a Nutshell" .

Cristi Diaconescu