调试 LINQ

Visual Studio 支持语言集成查询 (LINQ) 代码的调试,但存在一些限制。 大多数调试功能都适用于 LINQ 语句,包括单步执行、设置断点以及查看调试器窗口中的结果。 本主题介绍 LINQ 调试的主要限制。

查看 LINQ 结果

可以使用“数据提示”、“监视”窗口和“快速监视”对话框查看 LINQ 语句的结果。 在使用源窗口时,可以将指针停放在源窗口中的某个查询上,这样会出现“数据提示”。 可以复制 LINQ 变量并将其粘贴到“监视”窗口或“快速监视”对话框中。

在 LINQ 中,查询不会在创建或声明时进行计算,而只在使用时才进行计算。 因此,查询经过计算后才具有值。 有关查询创建和评估的完整说明,请参阅 LINQ 查询简介(C#)编写第一个 LINQ 查询

若要显示查询的结果,调试器必须对其进行计算。 当您在调试器中查看 LINQ 查询结果时,这种隐式求值会产生一些您需要考虑的影响:

  • 每个查询的评估都需要时间。 展开结果节点需要时间。 对于某些查询,重复评估可能会导致明显的性能损失。

  • 评估查询可能会导致副作用,这些副作用会更改数据值或程序的状态。 不是所有查询都具有副作用。 若要确定是否可以安全评估查询而不产生副作用,必须了解实现查询的代码。

单步执行和 LINQ

调试 LINQ 代码时,单步执行具有一些你应知道的行为差异。

LINQ to SQL

在 LINQ to SQL 查询中,谓词代码无法控制调试器。 因此,无法进入并单步执行谓词代码。 编译到表达式树的任何查询都会生成超出调试器控制的代码。

Visual Basic 中的单步执行

单步执行 Visual Basic 程序且调试器遇到查询声明时,调试器不会单步执行该声明,而是将整个声明作为单个语句突出显示。 发生此行为的原因是查询直到调用时才进行计算。 有关详细信息,请参阅 Visual Basic 中的 LINQ 简介

如果逐步执行以下示例代码,调试器会将查询声明或查询创建突出显示为一个单独的语句。

Function MyFunction(ByVal x As Char)
    Return True
End Function

Sub Main()
    'Query creation
    Dim x = From it In "faoaoeua" _
            Where MyFunction(it) _
            Select New With {.a = it}

    ' Query execution
    For Each cur In x
        Console.WriteLine(cur.ToString())
    Next
End Sub

当你再次单步执行时,调试器会突出显示 For Each cur In x。 在下一步中,调试器会单步执行函数 MyFunction。 单步调试 MyFunction 后,调试器跳回到 Console.WriteLine(cur.ToSting())。 调试器在任何时候都不会单步执行查询声明中的谓词代码,但调试器的确会计算该代码。

用函数替换谓词以启用单步执行 (Visual Basic)

如果必须单步执行谓词代码以进行调试,可以将谓词替换为对包含原始谓词代码的函数的调用。 例如,假设你有以下代码:

Dim items() as integer ={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

' Get the even numbers
Dim query = From nextInt in items Where nextInt Mod 2 = 0 Select nextInt

For each item in query
      Console.WriteLine(item)
Next

可以将谓词代码移动到名为 IsEven的新函数:

Dim items () as integer ={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

' Get the even numbers
Dim query = From nextInt in items Where IsEven(nextInt) Select nextInt

For each item in query
      Console.WriteLine(item)
Next
...
Function IsEven(item As =Integer) as Boolean
      Return item Mod 2 = 0
End Function

修订后的查询在每经过 items时调用函数 IsEven。 可以使用调试器窗口查看每个项是否满足指定条件,并且可以逐步执行 IsEven中的代码。 此示例中的谓词非常简单。 但是,如果必须调试一个更复杂的谓词,这种技术也会十分有用。

LINQ 不支持“编辑并继续”

“编辑并继续”支持对 LINQ 查询的更改,但存在限制。 有关详细信息,请参阅 EnC 支持的更改