如何debugging一个LINQ语句

我有一个Linq的对象声明

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

确认对象在System.Linq.Enumerable.WhereListIterator`1.MoveNext()处返回'Object Null or Not A Reference'

如果查询的结果是空的,它只会返回一个空的枚举器。 我知道这个事实,在声明中没有空对象。 是否有可能通过LINQ语句来查看它在哪里翻倒?

编辑当我说我知道有一个事实,没有空对象 ,事实certificate我是在说谎:[,但问题仍然存在,虽然我认为答案将是'你不能真正'

LINQPad是一个好主意,我用它来教我自己的LINQ,但我可能会开始再次把它看作是一个debugging/斜杠和刻录风格工具

我不确定是否可以从VS进行debugging,但是我发现LINQPad非常有用。 它会让你转储LINQ查询的每个部分的结果。

是的,确实可以通过linq查询中途暂停执行。

使用lambdaexpression式将linq转换为查询样式,并插入Select语句,该语句在要debugging的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;}在自己的行上,并在那里插入一个debugging点。 你可以把这个select放在你长而复杂的linq查询中的任何一点。

您应该能够在LINQ语句的where子句中的expression式上设置断点。

在这个例子中,将光标放在以下代码段的任何位置:

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

然后按F9或使用菜单或上下文菜单添加断点。

正确设置时,只有上面的代码应该在编辑器中具有断点格式,而不是整个LINQ语句。 你也可以在断点窗口看看。

如果设置正确,则每次都停止执行上述查询部分的function。

我在2010年撰写了一篇关于在Simple-Talk.com( LINQ秘密揭示:链接和debugging )上发表的关于这个问题的综合文章:

我将LINQPad作为Visual Studio 外部的一个很好的工具来讨论(就像前面提到的OwenP一样)。 特别注意其非凡的转储()方法。 您可以在LINQ链中的一个或多个点注入这些数据,以清晰明了的方式查看您的数据。 虽然非常有用,但LINQPad是Visual Studio的外部。 所以我也提供了几种 Visual Studio中使用的技术,因为有时将一段代码移植到LINQPad上是不现实的:

(1)注入调用到我的文章中存在的转储()扩展方法,以允许日志logging。 我从Bart De Smet的Watch()方法开始,在其内容丰富的文章“ LINQ to Objects – Debugging”中添加了一些标签和着色function,以增强可视化效果,但与LINQPad的Dump输出相比,它仍然很糟糕。

(2)使用Robert Ivanc的LINQPad Visualizer插件将LINQPad的可视化直接带入Visual Studio。 不知道是否是通过我的刺激:-),但是当我写文章的时候出现的那些不便之处现在在最新版本中已经得到了很好的解决。 它具有完整的VS2010支持,并允许您在debugging时检查您喜欢的任何对象。

(3)在LINQ链的中间embeddednop语句,这样就可以设置断点了,正如前面的Amazing Pete所描述的那样。

2016.12.01更新

我只是写了上面这篇文章的续作,简单的LINQdebugging和可视化 ,它揭示了真正的LINQdebuggingfunction终于到了Visual Studio 2015中,OzCode中即将发布的新function。 @Dror对这个问题的回答显示了它的一个小小的一瞥,但我鼓励你阅读我的新文章,以深入的“如何”。 (而我为OzCode。:-)

检查exception堆栈跟踪并查看执行的代码的最后一位。

从错误的外观我build议你看看line.Lines,并确保其枚举正确实施。 我认为它不应该返回null。

哦,只要确保线条和line.Lines对象不为空或返回空值。

[免责声明:我在OzCode工作]

LINQ的问题在于debugging是不可能的 – 即使在处理简单的查询时,开发人员也不得不将他/她的查询重构为一堆foreach循环,或者使用日志logging。 即将发布的OzCode版本( 目前可作为Early Access预览版 )支持LINQdebugging,它可以帮助开发人员深入研究他们的LINQ代码,并精确定位那些难以捕捉查询内部的exception

这就是你的查询在OzCode中的样子: 调试LINQ异常

可以在LINQexpression式内部进行,而不需要设置任何临时断点。 您需要进入评估 LINQexpression式的函数,例如:

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