2008-09-23 31 views
38

Tôi có một LINQ to đối tượng tuyên bốLàm thế nào để gỡ lỗi một Tuyên bố LINQ

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

Đối tượng xác nhận được trả lại một 'Object Null hay Not A Reference' ở tại System.Linq.Enumerable.WhereListIterator`1.MoveNext()

Nếu kết quả của truy vấn trống, nó sẽ chỉ trả lại một điều tra trống. Tôi biết thực tế là không có các đối tượng null trong câu lệnh. Có thể bước qua câu lệnh LINQ để xem nó nằm ở đâu không?

EDIT Khi tôi nói Tôi biết một thực tế rằng không có vô đối tượng nó quay ra tôi đang nằm: [, nhưng câu hỏi vẫn còn, mặc dù tôi đang asuming câu trả lời sẽ là 'bạn không thể thực sự'

LINQPad là một ý tưởng tốt, tôi sử dụng nó để dạy cho bản thân mình LINQ, nhưng tôi có thể bắt đầu nhìn vào nó một lần nữa như một debug/slash và ghi cụ phong cách

+0

Câu trả lời là gì? –

+3

42. Trên thực tế nếu bạn đọc chỉnh sửa của tôi, đó là tôi đã có một tham chiếu null, mặc dù đảm bảo của tôi để trái – johnc

Trả lời

27

tôi không chắc chắn nếu nó có thể gỡ lỗi từ VS, nhưng tôi thấy LINQPad là khá hữu ích. Nó sẽ cho phép bạn đổ kết quả của từng phần của truy vấn LINQ.

+6

Giống như phía bên kia của gối. – Dested

3

Kiểm tra dấu vết ngăn xếp ngoại lệ và xem bit cuối cùng của mã được thực thi.

+0

Đó là cách tôi truy cập vào System.Linq.Enumerable.WhereListIterator'1.MoveNext() – johnc

+0

Dòng cuối cùng của * mã * của bạn được thực hiện là gì? WhereListIterator không phải là mã của bạn (đó là API LINQ). –

3

Từ giao diện của lỗi, tôi khuyên bạn nên xem xét dòng. Hãy chắc chắn rằng điều tra viên của nó được triển khai đúng cách. Tôi nghĩ rằng nó trở về một null khi nó không nên.

Oh và chỉ đảm bảo đối tượng dòng và dòng.Lines không phải là null hoặc trả về giá trị rỗng.

14

Bạn sẽ có thể đặt điểm ngắt trên biểu thức trong mệnh đề where của câu lệnh LINQ của bạn.

Trong ví dụ này, hãy đặt con trỏ bất cứ nơi nào trong phần mã sau đây:

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

Sau đó nhấn F9 hoặc sử dụng menu hoặc menu ngữ cảnh để thêm breakpoint.

Khi được đặt chính xác, chỉ mã trên phải có định dạng điểm ngắt trong trình chỉnh sửa chứ không phải toàn bộ câu lệnh LINQ. Bạn cũng có thể xem trong cửa sổ điểm ngắt để xem.

Nếu bạn đã đặt chính xác, bạn sẽ ngừng mỗi lần tại hàm thực hiện phần trên của truy vấn.

+1

Đây có thể không phải là câu trả lời mà OP đang tìm kiếm, nhưng đã giúp tôi rất nhiều.Tôi nghĩ Visual Studio không thể gỡ rối các biểu thức lambda, chủ yếu là vì khi tôi chèn các điểm ngắt (với con trỏ ở cột sai), nó vẽ toàn bộ dòng, không chỉ lambda mà tôi muốn gỡ lỗi, mà còn vì cửa sổ Quick Watch không thể đánh giá các biểu thức lambda. – ygormutti

+0

Để làm rõ, trình gỡ rối sẽ nhập truy vấn LINQ sau * tham chiếu đầu tiên * tới biến chứa truy vấn LINQ –

29

Có thực sự có thể tạm dừng thực thi giữa chừng thông qua truy vấn LINQ.

Chuyển đổi LINQ thành kiểu truy vấn bằng cách sử dụng các biểu thức lambda và chèn câu lệnh Select tự quay về vị trí nào đó sau điểm trong LINQ mà bạn muốn gỡ lỗi. Một số mã mẫu sẽ làm cho nó rõ ràng hơn -

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

Sau đó, bỏ ghi chú dòng nhận xét. Đảm bảo {return i;} nằm trên một dòng riêng và chèn một điểm gỡ lỗi vào đó. Bạn có thể đặt lựa chọn này tại bất kỳ thời điểm nào trong truy vấn LINQ dài và phức tạp của bạn.

14

Tôi đã viết một bài báo toàn diện giải quyết vấn đề này được xuất bản trên Simple-Talk.com (LINQ Secrets Revealed: Chaining and Debugging) quay lại năm 2010:

Tôi nói về LINQPad (như đã đề cập trước đó bởi OwenP) như một công cụ tuyệt vời bên ngoài cho Visual Studio. Đặc biệt chú ý đến phương pháp Dump() đặc biệt của nó. Bạn có thể tiêm điều này tại một hoặc nhiều điểm trong chuỗi LINQ để xem dữ liệu của bạn được hiển thị trực quan một cách đáng kinh ngạc và rõ ràng. Mặc dù rất hữu ích, LINQPad là bên ngoài để Visual Studio. Vì vậy, tôi cũng trình bày một số kỹ thuật có sẵn để sử dụng trong phạm vi Visual Studio bởi vì đôi khi nó chỉ là không thực tế để di chuyển một đoạn mã trên LINQPad:

(1) Tiêm các cuộc gọi đến phương thức mở rộng Dump() bài viết của tôi cho phép đăng nhập. Tôi bắt đầu với phương pháp Watch() của Bart De Smet trong bài báo thông tin LINQ to Objects – Debugging của mình và thêm một số ghi nhãn và tô màu để tăng cường trực quan hóa, mặc dù nó vẫn có thể so sánh với đầu ra Dump của LINQPad.

(2) Đưa hình ảnh của LINQPad vào Visual Studio với phần bổ trợ LINQPad Visualizer của Robert Ivanc. Không chắc chắn nếu nó đã được thông qua prodding của tôi :-), nhưng các cặp vợ chồng bất tiện hiện nay khi tôi đã viết bài viết của tôi bây giờ tất cả đã được admirably địa chỉ trong phiên bản mới nhất. Nó có hỗ trợ đầy đủ VS2010 và cho phép bạn kiểm tra bất kỳ đối tượng nào bạn thích khi gỡ lỗi.

(3) Nhúng câu lệnh nop ở giữa chuỗi LINQ của bạn để bạn có thể đặt điểm ngắt, như được mô tả trước đó bởi Amazing Pete.

2016.12.01 Cập nhật

Và tôi chỉ viết phần tiếp theo của bài viết ở trên, với tựa đề đơn giản LINQ Debugging and Visualization, mà cho thấy rằng khả năng gỡ lỗi LINQ thật cuối cùng đã đến trong Visual Studio 2015 với khoảng-to-be tính năng mới được phát hành ở OzCode. @ Câu trả lời của Dror cho câu hỏi này cho thấy một cái nhìn thoáng qua của nó, nhưng tôi khuyến khích bạn đọc bài viết mới của tôi cho một chiều sâu "làm thế nào để". (Và tôi làm không hoạt động cho OzCode. :-)

3

Có thể bước vào bên trong biểu thức LINQ mà không cần đặt bất kỳ điểm ngắt tạm thời nào. Bạn cần phải bước vào chức năng mà đánh giá biểu thức LINQ, ví dụ:

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" 
    // ... 
+0

Nó hoạt động ngay cả với '.ToList()' – xleon

+1

Đây phải là câu trả lời được chấp nhận. –

3

[Disclaimer: Tôi làm việc tại OzCode]

Vấn đề với LINQ là thật khó để không thể debug - ngay cả khi xử lý các truy vấn đơn giản, nhà phát triển buộc phải tái cấu trúc truy vấn của mình thành một loạt các vòng lặp foreach hoặc sử dụng ghi nhật ký. LINQ gỡ lỗi được hỗ trợ trong phiên bản sắp được phát hành của OzCode (currently available as an Early Access Preview) và nó giúp các nhà phát triển khoan vào mã LINQ của họ như là tốt và xác định những khó khăn để bắt ngoại lệ bên trong truy vấn

Đây là những gì truy vấn của bạn sẽ trông giống như trong OzCode: Debugging LINQ exception

Các vấn đề liên quan