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 プログラムをステップ実行しているときに、デバッガーがクエリ宣言を検出すると、宣言にステップ インするのではなく、宣言全体が 1 つのステートメントとして強調表示されます。 この動作は、クエリが呼び出されるまで評価されないために発生します。 詳細については、「Visual Basicでの LINQ の概要」を参照してください。
次のコード例をステップ 実行すると、デバッガーによってクエリ宣言またはクエリの作成が 1 つのステートメントとして強調表示されます。
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 でサポートされる変更 を参照してください。
関連コンテンツ
- SQLデバッグ
- デバッガーを使用した例外の管理
- LINQ クエリの概要 (C#)
- Visual Basic での LINQ の概要