Подтвердить что ты не робот

Как отладить выражение LINQ

У меня есть оператор Linq для объектов

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

Объект подтверждения возвращает "Объект Null или Not A Reference" в System.Linq.Enumerable.WhereListIterator`1.MoveNext()

Если результат запроса был пуст, он просто вернул бы пустой счетчик. Я знаю, что в инструкции нет нулевых объектов. Можно ли выполнить оператор LINQ, чтобы увидеть, где он падает?

EDIT. Когда я сказал, что знаю, что нет нулевых объектов, оказывается, я лгал: [, но вопрос остается, хотя я предполагаю, что ответ будет "вы можете 't really'

LINQPad - хорошая идея, я использовал его, чтобы научить себя LINQ, но я могу снова взглянуть на него как инструмент отладки/слэша и стиля записи

4b9b3361

Ответ 1

Я не уверен, можно ли отлаживать VS, но я считаю LINQPad весьма полезным. Это позволит вам сбрасывать результаты каждой части запроса LINQ.

Ответ 2

Да, действительно возможно приостановить выполнение на полпути через запрос linq.

Преобразуйте свой linq в стиль запроса с помощью лямбда-выражений и вставьте оператор Select, который возвращает себя где-то после точки в linq, которую вы хотите отлаживать. Некоторые примеры кода станут более понятными -

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

Затем раскомментируйте прокомментированные строки. Убедитесь, что {return i;} находится в отдельной строке и вставляет туда отладочную точку. Вы можете поместить этот выбор в любую точку вашего длинного сложного запроса linq.

Ответ 3

Вы должны иметь возможность установить точку останова в выражении в предложении where вашего оператора LINQ.

В этом примере поместите курсор в любом месте в следующем разделе кода:

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

Затем нажмите F9 или используйте меню или контекстное меню, чтобы добавить точку останова.

При правильном настройке только указанный выше код должен иметь форматирование точки останова в редакторе, а не весь оператор LINQ. Вы также можете посмотреть в окне точек останова, чтобы увидеть.

Если вы установили его правильно, вы будете останавливаться каждый раз в функции, которая реализует вышеуказанную часть запроса.

Ответ 4

Я написал всеобъемлющую статью, посвященную этому самому вопросу, опубликованному на Simple-Talk.com(LINQ Secrets Show: Chaining and Debugging) назад 2010:

Я говорю о LINQPad (как упоминалось ранее OwenP) как отличный инструмент, внешний для Visual Studio. Обратите особое внимание на его необычный метод Dump(). Вы можете ввести это в одну или несколько точек в цепочке LINQ, чтобы увидеть, как ваши данные визуализируются удивительно чистым и понятным образом. Хотя он очень полезен, LINQPad является внешним по отношению к Visual Studio. Поэтому я также предлагаю несколько методов, доступных для использования в Visual Studio, потому что иногда просто нецелесообразно переносить кусок кода в LINQPad:

(1) Ввод вызовов в метод расширения Dump(), который я представляю в своей статье, чтобы разрешить ведение журнала. Я начал с метода Bart De Smet Watch() в своей информационной статье LINQ to Objects - Debugging и добавил некоторые маркировки и раскраски для улучшения визуализации, хотя все же он бледнеет по сравнению с выходом LINQPad Dump.

(2) Принесите визуализацию LINQPad прямо в Visual Studio с надстройкой Robert Ivanc LINQPad Visualizer. Не уверен, было ли это благодаря моему подталкиванию:-), но пара неудобств, присутствующих при написании моей статьи, теперь была превосходно рассмотрена в последнем выпуске. Он имеет полную поддержку VS2010 и позволяет вам проверять любой объект, который вам нравится при отладке.

(3) Вставьте nop-операторы в середине вашей линии LINQ, чтобы вы могли установить точки останова, как описано ранее Amazing Pete.

2016.12.01 Обновление

И я только что написал продолжение этой статьи под названием просто LINQ Debugging and Visualization, которая показывает, что истинная возможность отладки LINQ, наконец, прибыл в Visual Studio 2015 с новой функцией, появившейся в OzCode. Ответ @Dror на этот вопрос показывает крошечный взгляд на него, но я рекомендую вам прочитать мою новую статью для углубленного "как". (И я не работаю для OzCode.: -)

Ответ 5

Проверьте трассировку стека исключений и посмотрите последний бит исполняемого кода.

Ответ 6

Из взглядов ошибки я бы предложил вам взглянуть на строку line.Lines и убедиться, что ее перечислитель выполнен правильно. Я думаю, что он возвращает нуль, если это не так.

О, и просто убедитесь, что объекты line и line.Lines не являются нулевыми или возвращают нули.

Ответ 7

Можно выполнить вмешательство внутри выражения LINQ без установки временных контрольных точек. Вам нужно войти в функцию, которая оценивает выражение LINQ, например:

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

Ответ 8

[Отказ от ответственности: я работаю в OzCode]

Проблема с LINQ заключается в том, что ее трудно отлаживать - даже при использовании простых запросов разработчик вынужден реорганизовать свой запрос на кучу циклов foreach или использовать журналирование. Отладка LINQ поддерживается в скоро появляющейся версии OzCode (в настоящее время доступна как предварительный просмотр предварительного просмотра), и это помогает разработчикам развернуть в свой код LINQ и точно определить те, которые трудно поймать исключения внутри запросов

Это то, что ваш запрос будет выглядеть в OzCode: Отладка исключения LINQ