3

我是 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));

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

4

3 回答 3

7

对于这个看似简单的问题,可以写很多东西!事实上,我已经在 Simple-Talk.com 上的文章LINQ Secrets Revealed: Chaining and Debugging中详细写过。以下是其关键点的摘要:

  • 您可以使用调试器单步执行一些 LINQ 查询,但这取决于查询中表达式和语句的组成(因为您只能单步执行statements)。
  • LINQ 方法链之所以起作用,是因为有一个基本规则:每个非终端方法都将IEnumerable<T>其作为输入并IEnumerable<T>作为输出返回。
  • 你可以注入一个“no-op”语句来给你一个“垫脚石”,如果你愿意的话,只要它符合那个基本规则。也就是说,意识到您总是可以.Select(z => z)毫无后果地放入方法链中,请使用它的变体,即:z => { return z; }
  • 您可以类似地注入诊断方法来提供输出,而不仅仅是提供潜在的断点。LINQPad是出色的暂存器,不仅适用于 LINQ,而且通常适用于 C#,它以其强大的Dump()方法提供了这一点。Dump 是一个对象可视化工具,可提供复杂数据结构的惊人可视化。
  • 基于 Bart De Smet 在其内容丰富的文章LINQ to Objects - 调试您可以将简化的风格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);

在 Visual Studio 项目中包含 Dump 扩展方法后,您可以像这样最低限度地检测它...

Words
    .Select(word => word.Trim())
    .Dump()
    .Select(word => word.ToLower())
    .Dump()
    .Where(word => word.StartsWith("k"))
    .Dump()
    .OrderBy(word => word)
    .Dump();

...或者更详细地像这样...

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

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

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

于 2012-07-12T19:19:39.120 回答
1

我的做法是在查询中插入断点,或者使用名为 LINQPad 的工具。 http://www.linqpad.net/

于 2012-07-11T21:47:27.507 回答
0

我相信您应该能够像在任何其他代码中一样放置断点。我不是 100% 确定,因为我经常将 LINQ 语法写成匹配的扩展方法。

但是,这是另一种选择,您可以使用扩展方法重写查询并在每个方法上添加断点。

但是,如果有疑问,请使用 F11 :)

此外,LINQPad 应该能够在这里提供一些帮助。

于 2012-07-11T20:29:44.910 回答