如何调试LINQ结果

Tho*_*mas 3 c# linq debugging linq-to-objects

我是linq的新手.所以有时候只是不明白linq是如何工作的.所以在VS2010 IDE中有任何工具或内置机制来详细调试linq执行.假设我有这个linq查询

var to_search = new[] { "Geo", "JCB" };

var result = from sr in list
             let w = to_search.FirstOrDefault(ts => sr.Title.ToLower().Contains(ts.ToLower()))
             where w != null
             let a = new {sr=sr, word=w.ToLower()}
             group a by a.word into g
             orderby g.Count() descending
             let sorted = g.OrderByDescending(a=> a.sr.Title.Select((c, i) => a.sr.Title.Substring(i)).Count(sub => sub.ToLower().StartsWith(a.word)))
             from a in sorted 
             select a.sr;

var completeList = result.Concat(list.Except(result));
Run Code Online (Sandbox Code Playgroud)

如何详细调试上面的linq查询.请指导我.谢谢.

Mic*_*ens 6

为了回应这个看似简单的问题,可以写出很多内容!事实上,我已经在我的文章LINQ Secrets Revealed: Simple-Talk.com上的链接和调试中详细写了.以下是其要点摘要:

  • 您可以使用调试器进入某些LINQ查询,但这取决于查询中表达式和语句的组成(因为您只能单步执行语句).
  • LINQ方法链的工作原理是一个基本规则:每个非终端方法都接受IEnumerable<T>输入并IEnumerable<T>作为输出返回.
  • 如果你愿意的话,你可以注入一个"禁止操作"的声明来给你一个"垫脚石",只要它符合那个基本规则.也就是说,意识到你总是可以放入.Select(z => z)一个没有后果的方法链,使用它的变体,即:z => { return z; }.
  • 您可以类似地注入诊断方法来提供输出,而不是仅提供潜在的断点.LINQPad是一款出色的暂存器,不仅仅是LINQ而是C#,它以其强大的Dump()方法为幌子提供了这一功能.转储是一个对象可视化工具,可以提供复杂数据结构的惊人可视化.
  • 基于Bart De Smet在他的信息性文章LINQ to Objects - Debugging中的工作,您可以将简化的风格带Dump回到Visual Studio中 - 我提供了附在我在顶部提到的文章的代码.
  • 感谢Robert Ivanc在LINQPad Visualizer上的工作,您甚至可以将LINQPad可视化工具引入Visual Studio(尽管您需要手动为单个表达式启动它;您无法将其连接到Dump()方法).

作为一个简单的例子,请考虑这个简单的方法链:

string[] Words = new string[]
{"   KOOKABURRA", "Frogmouth", "kingfisher   ", "loon", "merganser"};

Words
        .Select(word => word.Trim())
        .Select(word => word.ToLower())
        .Where(word => word.StartsWith("k"))
        .OrderBy(word => word);
Run Code Online (Sandbox Code Playgroud)

一旦在Visual Studio项目中包含Dump扩展方法,就可以像这样最小化它...

Words
    .Select(word => word.Trim())
    .Dump()
    .Select(word => word.ToLower())
    .Dump()
    .Where(word => word.StartsWith("k"))
    .Dump()
    .OrderBy(word => word)
    .Dump();
Run Code Online (Sandbox Code Playgroud)

......或者更精心地像这样......

Words
    .Dump(w => "ORIGINAL: " + w, ConsoleColor.Yellow)
    .Select(word => word.Trim())
    .Dump(w => "TRIMMED: " + w, ConsoleColor.Yellow)
    .Select(word => word.ToLower())
    .Dump(w => "LOWERCASE: " + w, ConsoleColor.Green)
    .Where(word => word.StartsWith("k"))
    .Dump(w => "FILTERED to 'K': " + w, ConsoleColor.Red)
    .OrderBy(word => word)
    .Dump(w => "SORTED: " + w, ConsoleColor.Blue);
Run Code Online (Sandbox Code Playgroud)

...将输出分别呈现为图的左侧或右侧: Visual Studio中Dump方法的诊断输出

作为预告片,我会说虽然这确实很有用,但您必须看到LINQPad可以使用相同输出执行的增强可视化(为方便起见,这里再次提供链接).