web-dev-qa-db-ja.com

LINQステートメントをデバッグする方法

Linq to Objectsステートメントがあります

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

確認オブジェクトがSystem.Linq.Enumerable.WhereListIterator`1.MoveNext()で「オブジェクトNullまたは非参照」を返しています

クエリの結果が空の場合、空の列挙子を返します。ステートメントにはnullオブジェクトがないことを知っています。 LINQステートメントをステップ実行して、どこに落ちているかを確認することはできますか?

[〜#〜] edit [〜#〜]言ったときnullオブジェクトがないことを知っていますそれは私が嘘をついていたことが判明:[しかし、質問は残っていますが、答えは「あなたは本当にできない」と仮定していますが

LINQPadは良いアイデアです。私はそれを使ってLINQを独習しましたが、デバッグ/スラッシュおよび書き込みスタイルのツールとしてもう一度見始めるかもしれません

41
johnc

VSからデバッグできるかどうかはわかりませんが、 LINQPad は非常に便利です。 LINQクエリの各部分の結果をダンプできます。

29
OwenP

はい、実際にlinqクエリの途中で実行を一時停止することは可能です。

ラムダ式を使用してlinqをクエリスタイルに変換し、デバッグするlinqのポイントの後ろのどこかにそれ自体を返すSelectステートメントを挿入します。いくつかのサンプルコードはそれをより明確にします-

        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;}が独自の行にあることを確認し、そこにデバッグポイントを挿入します。この選択は、長くて複雑なlinqクエリの任意の時点に置くことができます。

31

LINQステートメントのwhere句の式にブレークポイントを設定できるはずです。

この例では、次のコードセクションの任意の場所にカーソルを置きます。

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

次に押す F9 または、メニューまたはコンテキストメニューを使用してブレークポイントを追加します。

正しく設定されている場合、LINQステートメント全体ではなく、上記のコードのみがエディターでブレークポイントの書式を設定する必要があります。ブレークポイントウィンドウで確認することもできます。

正しく設定すると、クエリの上記の部分を実装する関数で毎回停止します。

18
Steve Steiner

Simple-Talk.com( LINQ Secrets Revealed:Chaining and Debugging )で2010年に公開されたこの質問に対処する包括的な記事を書きました。

私は、LINQPad(OwenPが前述)をVisual Studioの優れたツールexternalと呼んでいます。その異常なDump()メソッドに特に注意してください。これをLINQチェーンの1つ以上のポイントに挿入して、驚くほどクリーンで明確な方法でデータを視覚化することができます。非常に便利ですが、LINQPadはVisual Studioの外部にあります。したがって、コードのチャンクをLINQPadに移行することが実際的でない場合があるため、Visual Studiowith内で使用できるいくつかの手法も紹介します。

(1)ロギングを許可するために、私の記事にあるDump()拡張メソッドへの呼び出しを挿入します。私は彼の有益な記事 LINQ to Objects – Debugging でBart De SmetのWatch()メソッドから始め、視覚化を強化するためにいくつかのラベル付けと色付けを追加しましたが、それでもLINQPadのダンプ出力と比較すると見劣りします。

(2)Robert Ivancの LINQPad Visualizer アドインを使用して、LINQPadの視覚化をVisual Studioに直接組み込みます。それが私の提案によるものかどうかはわかりませんが、私の記事を書いているときに存在していたいくつかの不便さは、すべて最新リリースで見事に対処されています。 VS2010を完全にサポートしており、デバッグ時に任意のオブジェクトを調べることができます。

(3)Amazing Peteが前述したように、ブレークポイントを設定できるように、LINQチェーンの途中にnopステートメントを埋め込みます。

2016.12.01アップデート

そして、私は単に上記の記事の続編を単にタイトルを付けた LINQ Debugging and Visualization というタイトルで書きました。これは、真のLINQデバッグ機能が、まもなくリリースされる新機能を備えたVisual Studio 2015に登場したことを明らかにしますOzCodeで。この質問に対する@Drorの回答はそれをほんの少し垣間見せていますが、詳細な「方法」については私の新しい記事を読むことをお勧めします。 (そして私はOzCodeのためにしない働きます:-)

15
Michael Sorens

[免責事項:私はOzCodeで働いています]

LINQの問題は、デバッグするのが難しいことです。単純なクエリを処理する場合でも、開発者は自分のクエリを一連のforeachループにリファクタリングするか、ロギングを使用する必要があります。 LINQデバッグは、近々リリースされるバージョンのOzCode( 現在、早期アクセスプレビュー として利用可能)でサポートされており、開発者がLINQコードにドリルインして正確に特定するのに役立ちますクエリ内で例外をキャッチするのが難しいもの

これは、クエリがOzCode: でどのようになるかです。Debugging LINQ exception

7
Dror Helper

一時的なブレークポイントを設定せずに、LINQ式の内部にステップインすることができます。 evaluates LINQ式の関数にステップインする必要があります。例:

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

例外スタックトレースをチェックして、実行されたコードの最後のビットを確認します。

エラーの外観から、line.Linesを見て、その列挙子が適切に実装されていることを確認することをお勧めします。私はそれがすべきでないときにnullを返すと思います。

ああ、ちょうどlineとline.Linesオブジェクトがnullでないこと、またはnullを返すことを確認してください。

3
ljs

これはデバッグの方法ではありませんが、以下を使用することをお勧めします。

using (var db = new AppContext())
        {
            db.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
            // Rest of code
        }

その後、デバッグ時に出力ウィンドウをチェックして、LINQクエリから生成されたSQLを確認できます。

0
Sha