Jak debugować instrukcję LINQ

Mam polecenie Linq to objects

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

Obiekt confirm zwraca 'Object Null or Not A Reference' w systemie at.Linq./ Align = "left" / Gdzie " 1.MoveNext ()

Jeśli wynik zapytania był pusty, zwróci on tylko pusty enumerator. Wiem na pewno, że w oświadczeniu nie ma obiektów null. Czy można przejść przez oświadczenie LINQ, aby zobaczyć, gdzie się przewraca?

EDIT Kiedy powiedziałem wiem na pewno, że nie ma obiektów null okazuje się, że kłamałem : [, ale pytanie pozostaje, choć odpowiedź będzie brzmiała "naprawdę nie możesz"

LINQPad jest dobrym pomysłem, użyłem go, aby nauczyć się LINQ, ale mogę zacząć patrzeć na niego ponownie jako narzędzie do debugowania / slash i wypalania stylu

Author: Valentin Rocher, 2008-09-23

8 answers

Nie jestem pewien, czy da się debugować Z VS, ale uważam, że LINQPad jest całkiem przydatny. Pozwoli Ci to zrzucić wyniki każdej części zapytania LINQ.

 27
Author: OwenP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 00:09:12

Tak, rzeczywiście możliwe jest wstrzymanie wykonania w połowie zapytania linq.

Konwertuj linq na styl zapytań za pomocą wyrażeń lambda i wstaw instrukcję Select, która zwraca się gdzieś po punkcie linq, który chcesz debugować. Jakiś przykładowy kod będzie jaśniejszy -

        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"));

Następnie odkomentuj skomentowane linie. Upewnij się, że {return i;} znajduje się we własnej linii i wstaw tam punkt debugowania. Możesz umieścić ten wybór w dowolnym momencie w swoim długim, skomplikowanym zapytanie linq.

 30
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-03 23:15:55

Powinieneś być w stanie ustawić punkt przerwania na wyrażeniu w klauzuli where Twojej instrukcji LINQ.

W tym przykładzie Umieść kursor w dowolnym miejscu w następującej sekcji kodu:

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

Następnie naciśnij F9 lub użyj menu lub menu kontekstowego, aby dodać punkt przerwania.

Po poprawnym ustawieniu tylko powyższy kod powinien mieć formatowanie punktu przerwania w edytorze, a nie całą instrukcję LINQ. Możesz również zajrzeć do okna punktów przerwania, aby zobaczyć.

Jeśli Ustawiłeś go poprawnie, za każdym razem zatrzymujesz się na funkcji, która implementuje powyższą część zapytania.

 14
Author: Steve Steiner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-25 01:11:09

Napisałem obszerny artykuł poruszający to właśnie pytanie opublikowany na Simple-Talk.com (Tajemnice LINQ ujawnione: Łańcuchowanie i debugowanie) w 2010 roku:

Mówię o LINQPad (jak już wcześniej wspomniał OwenP) jako świetnym narzędziu zewnętrznym do Visual Studio. Zwróć szczególną uwagę na jej niezwykłą metodę Dump (). Możesz wstrzyknąć to w jednym lub więcej punktach łańcucha LINQ, aby zobaczyć swoje dane wizualizowane w niezwykle przejrzysty i przejrzysty sposób. Choć bardzo przydatne, LINQPad jest zewnętrzny do Visual Studio. Dlatego też przedstawiam kilka technik dostępnych do użycia w ramach Visual Studio, ponieważ czasami po prostu nie jest praktyczna migracja fragmentu kodu do Linqpada:

(1) wywołania Inject do metody Dump () extension, którą przedstawiłem w moim artykule, aby umożliwić logowanie. Zacząłem od metody Watch() Barta de SMETA w jego artykule LINQ to Objects-Debugging {[2] } i dodałem etykietowanie i koloryzację, aby ulepszyć wizualizację, chociaż nadal blednie w porównaniu z wyjściem zrzutu Linqpada.

(2) Przenieś wizualizację Linqpada bezpośrednio do Visual Studio za pomocą dodatku Roberta Ivanca LINQPad Visualizer. Nie jestem pewien, czy to było przez moje prodding : -), ale kilka niedogodności obecne, gdy pisałem mój artykuł, teraz wszystkie zostały wspaniale omówione w najnowszym wydaniu. Ma pełną obsługę VS2010 i pozwala zbadać dowolny obiekt podczas debugowania.

(3) osadzanie instrukcji nop w środku Twojego łańcucha LINQ, dzięki czemu możesz ustawić punkty przerwania, jak opisano wcześniej przez Amazing Pete.

2016.12.01 Update

I właśnie napisałem sequel powyższego artykułu, zatytułowanego po prostu debugowanie i wizualizacja LINQ, który ujawnia, że prawdziwe możliwości debugowania LINQ w końcu przybył w Visual Studio 2015 z about-to-be-released nowa funkcja w OzCode. @Dror ' s odpowiedź na to pytanie pokazuje mały przebłysk tego, ale zachęcam do przeczytania mojego nowego artykułu dla szczegółowe "jak". (A ja pracuję , a nie dla OzCode.:-)

 14
Author: Michael Sorens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-04 01:29:12

[Zastrzeżenie: pracuję w OzCode]

Problem z LINQ polega na tym, że trudno jest debugować-nawet gdy programista zajmuje się prostymi zapytaniami, zmuszony jest refaktorować swoje zapytanie do kilku pętli foreach lub użyć logowania. Debugowanie LINQ jest wspierane w nadchodzącej wersji OzCode (obecnie dostępnej jako podgląd Wczesnego Dostępu) i pomaga programistom w wwierceniu się w ich kod LINQ i wskazaniu tych trudnych do wychwycenia WYJĄTKÓW w zapytaniach

Tak wyglądałoby Twoje zapytanie w OzCode:Debugowanie wyjątku LINQ

 4
Author: Dror Helper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-22 07:47:16

Sprawdź ślad stosu wyjątków i zobacz ostatni bit kodu, który został wykonany.

 3
Author: Judah Himango,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 00:14:15

Z wyglądu błędu proponuję spojrzeć na linię.Lines i upewnij się, że jego enumerator jest poprawnie zaimplementowany. Myślę, że zwraca null, kiedy nie powinno.

Oh I upewnij się, że linia i linia.Obiekty Lines również nie są null ani zwracają null.

 3
Author: ljs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 00:15:03

Można wejść do wyrażenia LINQ bez ustawiania żadnych tymczasowych punktów przerwania. Musisz przejść do funkcji, która ocenia wyrażenie LINQ, np.:

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"
    // ...
 3
Author: user1414213562,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-10 08:32:10