Mẹo debug với Visual Studio 2010

Bài viết này được bạn Nguyễn Thị Linh dịch từ nguồn ScottGu’s Blog.

Hôm nay blog đăng 1 vài mẹo debug hữu ích mà bạn có thể sử dụng với Visual Studio. Những mẹo hay cho hầu hết các developer(người phát triển ứng dụng) sử dụng Visual Studio dường như không biết (mặc dù hầu hết đã có trong sản phẩm). Hi vọng rằng bài viết này sẽ giúp bạn khám phá chúng. Chúng rất dễ học, và có thể giúp bạn tiết kiệm thời gian

Run to Cursor (Chạy với con trỏ)(Ctrl + F10)

Thông thường bạn nhìn mọi người debug ứng dụng bằng cách nhấn vào breakpoint ở đầu dòng và sau đó lại sử dụng F10/F11 để chạy từng bước theo code cho đến đoạn code thực sự muốn debug. Trong một vài trường hợp họ quan sát cẩn thận mỗi câu lệnh khi mà nhấn từng bước (khi dùng F10/F11). Tuy nhiên mọi người chỉ cố nhanh chóng đến dòng code mà họ thực sự quan tâm – trong trường hợp này F10/F11 không phải là cách tốt nhất

Thay vào đó, bạn có thể tận dụng tính năng “chạy con trỏ chuột” được hỗ trợ bở chương trình debug. Đơn giản là đặt vị trí con trỏ trên dòng code mà bạn muốn chạy ứng dụng, sau đó nhấn tổ hợp phím Ctrl + F10.Điều này sẽ chạy ứng dụng đến vị trí dòng bạn muốn debug – tránh việc phải dùng F10/F11 nhiều lần. Nó làm việc ngay cả với dòng code chạy trong các hàm hoặc lớp riêng của chương trình debug hiện tại

Conditional Breakpoints (điều kiện breakpoints)

Một điều phổ biến khác mà chúng ta thường thấy là các trường hợp nơi mà developer đặt breakpoint, chạy ứng dụng, thử đầu vào, nhấn 1 breakpoint, và tự kiểm tra, nếu một vài điều kiện đúng trước khi quyết định kiểm tra thêm. Nếu kịch bản không phù hợp với những gì họ đang có, họ nhấn F5 để tiếp tục ứng dụng, thêm vài đầu vào khác và lặp lại quá trình thủ công

Điều kiện breakpoint của Visual Studio có khả năng cung cấp nhiều cách dễ hơn để xử lý điều này. Điều kiện breakpoint cho phép bạn nhấn(break) chỉ khi nếu 1 vài điều kiện cụ thể mà bạn chỉ định. Chúng giúp bạn tránh việc kiểm tra hoặc bắt đầu lại 1 cách thông thường ứng dụng, và bạn có thể làm cho toàn bộ quá trình debug nhanh hơn rất nhiều theo hướng dẫn sử dụng và đỡ tẻ nhạt.

Làm thế nào để kích hoạt 1 breakpoint có điều kiện

Thiết lập 1 breakpoint có điều kiện rất dễ dàng. Nhấn F9 trong code để đặt 1 breakpoint trên 1 dòng cụ thể

Sau đó kích chuột phải trên breakpoint “vòng tròn màu đỏ” và chọn “Condition”

Nó sẽ hiện ra 1 hộp thoại cho phép bạn chỉ định breakpoint nếu điều kiện đúng. Ví dụ, chúng ta có thể chỉ ra rằng chúng ta muốn break nếu kích thước của danh sách vùng paginatedDinners ít hơn 10 bằng việc viết biểu thức sau:

Bây giờ khi tôi chạy lại ứng dụng và làm 1 cái tìm kiếm, chương trình debug sẽ chỉ chạy nếu tôi thực hiện 1 cái tìm kiếm trả về ít hơn 10 dinners. Nếu mà nhiều hơn 10 dinners(bữa ăn) thì breakpoint sẽ không bị ảnh hưởng.

Hit Count Feature (Tính năng đếm số lượt)

Đôi lúc bạn chỉ muốn break 1 điều kiện số lần đúng. Ví dụ chỉ break 5 lần ít hơn 10 dinners được trả về từ việc tìm kiếm

Bạn có thể kích hoạt bằng cách click chuột phải về breakpoint và chọn lệnh “Hit count”

Sẽ có 1 hộp thoại cho phép bạn chỉ ra breakpoint mà được đếm số lần 1 điều kiện được đáp ứng, hoặc là tất các lần được đáp ứng, hoặc các lần sau n lần xuất hiện

Machine/Thread/Process Filtering (Bộ máy/ luồng/quá trình lọc)

Bạn có thể kích chuột phải trên breakpoint và chọn lệnh “Filter..” để chỉ ra rằng 1 breakpoint chỉ được nhấn nếu xảy ra trên 1 bộ máy cụ thể, hoặc 1 quá trình cụ thể, hoặc 1 luồng cụ thể

TracePoints (theo dõi điểm) – Custom Actions When Hitting a BreakPoint


(tùy chỉnh hoạt động khi nhấn 1 breakpoint)

Một tính năng debug nhiều người không biết là khả năng sử dụng TracePoint. Một TracePoint là 1 breakpoint mà có 1 số hoạt động tùy chỉnh gây ra khi breakpoint được nhấn. Tính năng này đặc biệt hữu dụng khi mà bạn muốn quan sát hành vi trong ứng dụng mà không vi phạm vào trình gỡ lỗi (the debugger)

Tôi sẽ sử dụng 1 ứng dụng Console để chứng minh làm thế nào chúng ta có thể tận dụng lợi thế của TracePoints. Bên dưới là 1 thực hiện đệ quy của Fibonacci sequence ( là dãy vô hạn các số tự nhiên bắt đầu bằng hai phần tử 0 và 1, các phần tử sau đó được thiết lập theo quy tắc mỗi phần tử luôn bằng tổng hai phần tử trước nó)

Trong ứng dụng trên, chúng ta sử dụng Console.Writeline() để đưa ra giá trị dãy đệ quy Fibonacci cuối cùng cho 1 đầu vào cụ thể. Điều gì xảy ra nếu chúng ta muốn quan sát trình tự dãy đệ quy Fibonacci hoạt động trong chương trình debug – mà không dừng việc thực thi của nó? TracePoint giúp bạn dễ dàng làm điều này

Setting up a TracePoint (Thiết lập 1 TracePoint)

Bạn có thể kích hoạt 1 TracePoint bằng cách sử dụng F9 để đặt 1 breakpoint trên 1 dòng code, sau đó kích chuột phải trên breakpoint và chọn lệnh “When Hit..”

Sẽ xuất hiện 1 hộp thoại cho phép bạn chỉ định những gì nên xảy ra khi breakpoint được nhấn

Ở trên chỉ ra rằng bạn muốn in thông báo theo dõi bất cứ lúc nào điều kiện breakpoint được đáp ứng. Bạn muốn giá trị đầu ra của biến x như 1 phần của thông báo. Biến cục bộ có thể tham chiếu sử dụng cú pháp {variableName}. Cũng có lệnh được xây dựng (như $CALLER, $CALLSTACK, $FUNCTION,…) có thể được sử dụng cho ra giá trị chung trong thông báo theo dõi của bạn

Chúng ta cũng có thể tích vào hộp chọn “continue execution” ở dưới cùng – điều này chỉ ra rằng chúng ta không muốn ứng dụng bị ngắt trong chương trình debug. Thay vào đó nó sẽ tiếp tục chạy – với chỉ một sự khác biệt duy nhất rằng thông báo theo dõi tùy chính sẽ cho ra mỗi lần điều kiện breakpoint được đáp ứng

Và bây giờ khi chúng ta chạy ứng dụng sẽ thấy rằng thông báo theo dõi tùy chỉnh tự động hiện ra cửa số “output” của Visual Studio – cho phép chúng ta theo dõi hành động đệ quy của ứng dụng

Bạn có thể lựa chọn wire-up lắng nghe theo dõi tùy chỉnh trong ứng dụng của bạn – trong trường hợp này các thông báo bạn in từ TracePoints sẽ được dẫn ra thay vì cửa sổ đầu ra VS

TracePoint – Running a Custom Macro (Chạy như 1 Custom Macro)

Trong 1 bài nói chuyện tôi đã đưa ra lần trước ở London, 1 vài khán giả yêu cầu liệu nó có thể tự động xuất ra tất cả các biến cụ bộ khi 1 TracePoint được nhấn

Khả năng này không được xây dựng trong Visual Studio – nhưng có thể kích hoạt bằng cách viết 1 Macro(macro là một chương trình con được viết sẵn theo một mục đích nào đó, để thi hành một lệnh , một công việc nào đó theo nguyện vọng của người lập trình) tùy chỉnh trong Visual Studio, và sau đó dẫn 1 TracePoint để gọi đến Macro khi nó được nhận ra. Để kích hoạt điều này, mở Macros IDE trong Visual Studio (Tools->Macros->Macros IDE menu command). Sau đó dưới nút MyMacros của project, chọn 1 module hoặc tạo cái mới (ví dụ: thêm 1 tên là (“UsefulThings”)). Sau đó paste code macro VB sau đây vào module và lưu nó:

Sub DumpLocals()

Dim outputWindow As EnvDTE.OutputWindow

outputWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutpu.Object

Dim currentStackFrame As EnvDTE.StackFrame

currentStackFrame = DTE.Debugger.CurrentStackFrame

outputWindow.ActivePane.OutputString(“*Dumping Local Variables*” + vbCrLf)

For Each exp As EnvDTE.Expression In currentStackFrame.Locals

outputWindow.ActivePane.OutputString(exp.Name + ” = “ +exp.Value.ToString() + vbCrLf)

Next

End Sub

Trên đoạn vòng lặp code macro thông qua cụm cấu trúc hiện tại và kiết xuất tất cả biến cục bộ lên cửa sổ đầu ra

Sử dụng DumpLocals Custom Macro

Chúng ta có thể tận dụng lợi thế của macro “DumpLocals” tùy chỉnh bằng cách sử dụng ứng dụng bổ sung đơn giản dưới đây:

Chúng ta sẽ sử dụng F9 để đặt 1 breakpoint trên câu lệnh trả về trong phương thức “Add” ở trên. Sau đó click chuột phải trên breakpoint và chọn lệnh “When hit”

Sẽ có 1 hộp thoại bên dưới. Không như trước nơi mà chúng ta sử dụng hộp lựa chọn “In ra 1 thông báo”(print a message) và quy định bằng tay các biến mà muốn hiển thị đầu ra, lúc này thay vì chọn “Run a macro” và trỏ đến UsefulThings tùy chỉnh. Macro DumpLocals tạo bên dưới:

Chúng ta sẽ giữ hộp đánh dấu “continue execution” để chương trình tiếp tục chạy thậm chí khi TractPoints được nhấn

Runing a Application (chạy 1 ứng dụng)

Bây giờ khi nhấn F5 và chạy ứng dụng, ta sẽ nhìn thầy đầu ra hiện bên dưới trong cửa sổ “output” của Visual Studio khi phương thức Add được gọi. Lưu ý cách mà macro tự động liệt kê tên và giá trị của mỗi biến cục bộ khi TracePoint được nhấn:

Tóm tắt

Chương trình debug Visual Studio vô cùng phong phú. Tôi khuyên bạn nên dành thời gian để thực sự tìm hiểu tất cả các tính năng của nó. Mẹo và thủ thuật ở trên chỉ là một vài trong rất nhiều tính năng nó cung cấp mà hầu hết mọi người không biết.

Những tính năng đơn giản nhưng thú vị của VS2010 và C# 4.0

Giới thiệu

VS 2010 và C#4.0 được giới thiệu có rất nhiều tính năng mới. Trong bài viết này, tôi sẽ cố gắng trình bày những tính năng đơn giản và hữu ích nhất của chúng.

1. Ẩn phần code được chọn

Nhiều khi, tình huống phát sinh khi chúng ta muốn ẩn một đoạn thay vì toàn bộ code. Việc này sẽ dễ dàng hơn trong VS 2010. Chỉ cần chọn phần code bạn muốn ẩn và nhấp chuột phải chọn Outlining – Hide Selection

Cách tương tự một vùng mã có thể đóng và mở rộng. Bất cứ khi nào bạn muốn hiện lại đoạn mã, nhấp chuột phải rồi chọn Outlining -> Stop Hiding Current.

2. DataTips

Lựa chọn này cung cấp cho ta cách đơn giản hơn để giao tiếp với bất kỳ biến nào lúc debug. Trong VS 2010, DataTip có thể được đặt cố định ở một vị trí hay để trôi nổi. Điều này giúp bạn dễ dàng hơn trong quá trình theo dõi các biến và giá trị của nó trong suốt quá trình debug. Ta có thể thêm nhiều DataTips và thậm chí các datatips này có thể duy trì sau khi phiên làm việc (session) kết thúc.

Để thêm ghim(Pin) vào DataTip, chỉ cần di chuyển con trỏ chuột qua bất kỳ biến nào là bạn có thể nhìn thấy biểu tượng pin

Bạn có thể di chuyển pin đến bất kỳ vị trí nào. Pin cung cấp ba nút: Close, Unpin(để gỡ pin). Expand (để thêm chú thích)

Có khi code đã được debug nhưng chúng ta vẫn muốn nhìn lại giá trị của biến/biểu thức được giữ trong lúc debug, do đó đó tính năng này rất hữu ích.

Bạn có thể xuất/nhập(Export/Import) DataTips của mình bằng cách nhấp chuột vào Debug -> Export DataTips -> Xác định vị trí tệp XML bạn muốn được lưu.

Bạn có thể truy cập vào tệp XML của bạn mọi lúc bằng cách chọn Import trên Debug – > Import DataTips

3. String.IsNullOrWhiteSpace

Phương thức này kiểm tra một chuỗi xác định là trống, null hay chỉ các ký tự khoảng trắng. Nếu chuỗi chứa bất bất cứ trường hợp nào kể trên hoặc ký tự đặc biệt dưới đây thì phương thức sẽ trả về true

“\n”: xuống dòng

” \r” : trở về đầu dòng

“\v”: để tab theo cột

Các ký tự khoảng trắng (dấu cách)

“\t”: cho ký tự Tab

4. Đặt tên và tham số tùy chọn

Tham số VS2010 trở thành tùy chọn khi giá trị được gán mặt định

Trong phương thức trên, ta có thể quên Val1 và Val2 do chúng có giá trị mặc định và có thể coi là tùy chọn. Lúc này ta bắt đầu gõ phương thức, gợi ý sẽ hiển thị các tham số tùy chọn

Đặt tên đối số cho phép người dùng không phải nhớ thứ tự các tham số. Nếu biết tên tham số, bạn có thể gọi chúng theo bất kỳ thứ tự nào. Hỗ trợ thông minh đặt tên đối số bằng tên tham số theo sau dấu hai chấm

Đây là một ví dụ đầy đủ về tùy chọn và đặt tên đối số

5. Làm nổi bật (Highlighting)

Chọn một định danh bất kỳ trong code và tất cả những vị trí có định danh này sẽ được làm nổi bật (Highlighting)

Trong ví dụ bên dưới, tôi đã chọn Val2 và tất cả những chỗ sử dụng từ đó được tự động highlight.

6. Tự sinh code một cách thông minh tùy ngữ cảnh sử dụng

Tính năng này khá thú vị. Tôi đã trải nghiệm nó khi tạo một lớp test và trong khi khai báo đối tượng, do tôi viết lỗi và nó cho phép tôi tạo một đối tượng với dòng bị đỏ

Khi nhìn dòng bị đỏ, tôi chỉ cần nhấp chuột phải và nhìn các lựa chọn được gọi ra, gồm: Class và New Type. Sự thông minh được cải tiến rất nhiều nên cho phép nếu bất kỳ phương thức nào chưa có trong lớp có thể được sử dụng trước khi tạo ra nó

7. Định tuyến URL (URL Routing)

Việc ánh xạ URL có thể mở rộng tới một mức độ nhất định trong ASP.NET 2.0. Ta có thể định nghĩa URL để hiển thị nhưng vấn đề là trong trường hợp postback, URL thực ở trình duyệt sẽ bị hiển thị URL routing được giới thiệu trong ASP.NET 3.5. Vấn đề của PostBack được giải quyết khi ta tạo các lớp xử lý khác phụ thuộc vào số định tuyến URL.

Trong ASP.NET 4.0 cần định nghĩa các lớp xử lý riêng cho mỗi định tuyến đã bị xóa và xây dựng hàm hỗ trợ đặt tên là MapPageRoute để giúp triển khai định tuyến nhanh hơn. Những route này được đăng ký onApplication_Start

Cùng làm định tuyến trong một ví dụ đơn giản. Tôi có hai trang default và default2. Và trên mỗi trang có một nút để đến trang tiếp theo. Cùng với đó, di chuyển từ trang này sang trang khác, tôi cũng cần gửi đi một tham số.

Đầu tiên trong tệp global.asax dưới Application_Start, ta phải đăng ký URL cái mà ta muốn xuất hiện trên trình duyệt.

default sẽ có đường dẫn MyfirstPage/Value trong tên tham số và default2 sẽ có đường dẫn MySecongPage/value trong tên tham số

Khi bấm vào nút của trang mặc định, tôi phải thêm mã để gọi trang default2

“An” là giá trị của tham số Name, và một đoạn code tương tự được thêm vào trang default2 để trở lại trang default

Định tuyến trở lên dễ dàng và đơn giản hơn. Ta cũng có thể có qua nhiều hơn một tham số

8. Hỗ trợ ngôn ngữ động

Ngôn ngữ động (Dynamic Language) là thứ không được kiểm tra trong thời gian-biên dịch (compile-time), mà chúng chỉ được xác định là đối tượng trong thời gian chạy (runtime). Viết nó nhanh và dễ hơn nhưng ta không thể nhìn thấy lỗi biên dịch. Vì vậy ta phải chắc chắn ứng dụng xử lý như mong muốn.

Nếu ta xem các phiên bản trước của C# là ngôn ngữ tĩnh hoàn toàn, nhưng 4.0 được thêm yếu tố động (dynamic) để hỗ trợ tính năng động. Sử dụng từ khóa dynamic nghĩa là nói với trình biên dịch tắt việc kiểm tra khi biên dịch

Bay giờ đến một câu hỏi rất hiển nhiên, sự khác biệt giữa kiểu Object, Var và Dynamic là gì. Cùng xem:

Đối tượng (Object) Dynamic Var
Trình biên dịch có thông tin về kiểu của biến Không có thông tin với trình biên dịch Trình biên dịch hoàn tất thông tin
Biến yêu cầu chọn trước khi sử dụng Không yêu cầu chọn Không yêu cầu chọn, do trình biên dịch đã hoàn tất thông tin
Nếu ta không có nhiều thông tin của kiểu dũ liệu, nó rất hữu dụng Khi ta cần viết ít mã và sử dụng ngôn ngữ động Thường sử dụng với Linq

9. Tạo ra ClientID bằng cách sử dụng ClientIDMode

Trong ASP.NET, nếu ta nhìn bên phía client thì rất khó để đoán được ClientId của trang là gì. ASP.NET sử dụng một hệ thống tên duy nhất cho việc tạo ClientId

Nhưng giờ với ASP.NET 4.0, xử lý ClientID trở lên dễ dàng. Ta đã thấy nếu thêm bất kỳ control nào trên trang aspx và xem nguồn code, ta có thể thấy id của vài control tương tự như “ctl00_MainContent_txtName”. Bây giờ ta có thể đặt ID mong muốn cho thuộc tính của ClientIDMode.

ASP.NET 4.0 hỗ trợ bốn kiểu chế độ cho thuộc tính ClientIDMode

Tự động (Auto)

ID của ASP.NET 2.0/3.0/3.5 được tạo ra cho đến nay

Ví Dụ

Khi ta xem nguồn của nó, ClientId được tạo ra là “ctl00_MainContent_txtData” :

Tĩnh (Static)

Chế độ này đặt ID tĩnh bên phía client, nghĩa là ID đã đăng ký để điểu khiển phía server cũng sẽ được sử dụng cho ID phía client. Nhưng nếu chế độ đặt là tĩnh cho việc kiểm soát lặp đi lặp lại thì trách nhiệm của nhà phát triển là đảm bảo tính duy nhất của ID phía client

Ví dụ

Nhìn vào nguồn của nó, Client Id được tạo ra là “divVal3″

Khả năng dự đoán (Predictable)

Khả năng dự đoán phụ thuộc vào tên cha của control ClientID để tạo giá trị ID client riêng. Nó có tên cha gạch dưới tên control, không gồm ctxxx. Điều này rất hữu ích cho control DataBound

Ví dụ

Xem nguồn của nó:

Kế thừa (Inherit)

Đây là trạng thái mặc định cho mọi control. Nó tìm đến control cha để lấy giá trị cho ClientIDModel

Ví dụ

Nó không đề cập đến bất kỳ chế độ nào, mặc định là Inherit

Ta có thể đặt các thuộc tính này theo ba cách:

1. Mức độ control (control level)

2. Mức độ trang (Page Level)

3. Mức độ ứng dụng (Application Level)

Trong tệp web.config, đặt dưới system.web. Nó hữu dụng khi nâng cấp ứng dụng từ 2.0/3.0/3.5 lên 4, lúc đó chế độ mặc định thời gian sẽ tự động vì vậy tất cả control sẽ trả lại tự động, nhưng lúc bạn nâng cấp lên 4, nó sẽ được đoán trước. Vậy để code làm việc, ta đặt clientIDMode=”Auto” trong tệp web.config

Kết luận

Tôi đã tạo ra một ứng dụng mẫu sử dụng tất cả các tính năng đã đề cập ở trên. Đây chưa phải kết thúc, mới chỉ là bắt đầu khám phá các tính năng của VS2010. Nó thực sự thú vị khi tìm hiểu sâu những tính năng này và nhiều hơn nữa

Mẹo debug với Visual Studio 2010

Bài viết này được bạn Nguyễn Thị Linh dịch từ nguồn ScottGu’s Blog.

Hôm nay blog đăng 1 vài mẹo debug hữu ích mà bạn có thể sử dụng với Visual Studio. Những mẹo hay cho hầu hết các developer(người phát triển ứng dụng) sử dụng Visual Studio dường như không biết (mặc dù hầu hết đã có trong sản phẩm). Hi vọng rằng bài viết này sẽ giúp bạn khám phá chúng. Chúng rất dễ học, và có thể giúp bạn tiết kiệm thời gian

Run to Cursor (Chạy với con trỏ)(Ctrl + F10)

Thông thường bạn nhìn mọi người debug ứng dụng bằng cách nhấn vào breakpoint ở đầu dòng và sau đó lại sử dụng F10/F11 để chạy từng bước theo code cho đến đoạn code thực sự muốn debug. Trong một vài trường hợp họ quan sát cẩn thận mỗi câu lệnh khi mà nhấn từng bước (khi dùng F10/F11). Tuy nhiên mọi người chỉ cố nhanh chóng đến dòng code mà họ thực sự quan tâm – trong trường hợp này F10/F11 không phải là cách tốt nhất

Thay vào đó, bạn có thể tận dụng tính năng “chạy con trỏ chuột” được hỗ trợ bở chương trình debug. Đơn giản là đặt vị trí con trỏ trên dòng code mà bạn muốn chạy ứng dụng, sau đó nhấn tổ hợp phím Ctrl + F10.Điều này sẽ chạy ứng dụng đến vị trí dòng bạn muốn debug – tránh việc phải dùng F10/F11 nhiều lần. Nó làm việc ngay cả với dòng code chạy trong các hàm hoặc lớp riêng của chương trình debug hiện tại

Conditional Breakpoints (điều kiện breakpoints)

Một điều phổ biến khác mà chúng ta thường thấy là các trường hợp nơi mà developer đặt breakpoint, chạy ứng dụng, thử đầu vào, nhấn 1 breakpoint, và tự kiểm tra, nếu một vài điều kiện đúng trước khi quyết định kiểm tra thêm. Nếu kịch bản không phù hợp với những gì họ đang có, họ nhấn F5 để tiếp tục ứng dụng, thêm vài đầu vào khác và lặp lại quá trình thủ công

Điều kiện breakpoint của Visual Studio có khả năng cung cấp nhiều cách dễ hơn để xử lý điều này. Điều kiện breakpoint cho phép bạn nhấn(break) chỉ khi nếu 1 vài điều kiện cụ thể mà bạn chỉ định. Chúng giúp bạn tránh việc kiểm tra hoặc bắt đầu lại 1 cách thông thường ứng dụng, và bạn có thể làm cho toàn bộ quá trình debug nhanh hơn rất nhiều theo hướng dẫn sử dụng và đỡ tẻ nhạt.

Làm thế nào để kích hoạt 1 breakpoint có điều kiện

Thiết lập 1 breakpoint có điều kiện rất dễ dàng. Nhấn F9 trong code để đặt 1 breakpoint trên 1 dòng cụ thể

Sau đó kích chuột phải trên breakpoint “vòng tròn màu đỏ” và chọn “Condition”

Nó sẽ hiện ra 1 hộp thoại cho phép bạn chỉ định breakpoint nếu điều kiện đúng. Ví dụ, chúng ta có thể chỉ ra rằng chúng ta muốn break nếu kích thước của danh sách vùng paginatedDinners ít hơn 10 bằng việc viết biểu thức sau:

Bây giờ khi tôi chạy lại ứng dụng và làm 1 cái tìm kiếm, chương trình debug sẽ chỉ chạy nếu tôi thực hiện 1 cái tìm kiếm trả về ít hơn 10 dinners. Nếu mà nhiều hơn 10 dinners(bữa ăn) thì breakpoint sẽ không bị ảnh hưởng.

Hit Count Feature (Tính năng đếm số lượt)

Đôi lúc bạn chỉ muốn break 1 điều kiện số lần đúng. Ví dụ chỉ break 5 lần ít hơn 10 dinners được trả về từ việc tìm kiếm

Bạn có thể kích hoạt bằng cách click chuột phải về breakpoint và chọn lệnh “Hit count”

Sẽ có 1 hộp thoại cho phép bạn chỉ ra breakpoint mà được đếm số lần 1 điều kiện được đáp ứng, hoặc là tất các lần được đáp ứng, hoặc các lần sau n lần xuất hiện

Machine/Thread/Process Filtering (Bộ máy/ luồng/quá trình lọc)

Bạn có thể kích chuột phải trên breakpoint và chọn lệnh “Filter..” để chỉ ra rằng 1 breakpoint chỉ được nhấn nếu xảy ra trên 1 bộ máy cụ thể, hoặc 1 quá trình cụ thể, hoặc 1 luồng cụ thể

TracePoints (theo dõi điểm) – Custom Actions When Hitting a BreakPoint


(tùy chỉnh hoạt động khi nhấn 1 breakpoint)

Một tính năng debug nhiều người không biết là khả năng sử dụng TracePoint. Một TracePoint là 1 breakpoint mà có 1 số hoạt động tùy chỉnh gây ra khi breakpoint được nhấn. Tính năng này đặc biệt hữu dụng khi mà bạn muốn quan sát hành vi trong ứng dụng mà không vi phạm vào trình gỡ lỗi (the debugger)

Tôi sẽ sử dụng 1 ứng dụng Console để chứng minh làm thế nào chúng ta có thể tận dụng lợi thế của TracePoints. Bên dưới là 1 thực hiện đệ quy của Fibonacci sequence ( là dãy vô hạn các số tự nhiên bắt đầu bằng hai phần tử 0 và 1, các phần tử sau đó được thiết lập theo quy tắc mỗi phần tử luôn bằng tổng hai phần tử trước nó)

Trong ứng dụng trên, chúng ta sử dụng Console.Writeline() để đưa ra giá trị dãy đệ quy Fibonacci cuối cùng cho 1 đầu vào cụ thể. Điều gì xảy ra nếu chúng ta muốn quan sát trình tự dãy đệ quy Fibonacci hoạt động trong chương trình debug – mà không dừng việc thực thi của nó? TracePoint giúp bạn dễ dàng làm điều này

Setting up a TracePoint (Thiết lập 1 TracePoint)

Bạn có thể kích hoạt 1 TracePoint bằng cách sử dụng F9 để đặt 1 breakpoint trên 1 dòng code, sau đó kích chuột phải trên breakpoint và chọn lệnh “When Hit..”

Sẽ xuất hiện 1 hộp thoại cho phép bạn chỉ định những gì nên xảy ra khi breakpoint được nhấn

Ở trên chỉ ra rằng bạn muốn in thông báo theo dõi bất cứ lúc nào điều kiện breakpoint được đáp ứng. Bạn muốn giá trị đầu ra của biến x như 1 phần của thông báo. Biến cục bộ có thể tham chiếu sử dụng cú pháp {variableName}. Cũng có lệnh được xây dựng (như $CALLER, $CALLSTACK, $FUNCTION,…) có thể được sử dụng cho ra giá trị chung trong thông báo theo dõi của bạn

Chúng ta cũng có thể tích vào hộp chọn “continue execution” ở dưới cùng – điều này chỉ ra rằng chúng ta không muốn ứng dụng bị ngắt trong chương trình debug. Thay vào đó nó sẽ tiếp tục chạy – với chỉ một sự khác biệt duy nhất rằng thông báo theo dõi tùy chính sẽ cho ra mỗi lần điều kiện breakpoint được đáp ứng

Và bây giờ khi chúng ta chạy ứng dụng sẽ thấy rằng thông báo theo dõi tùy chỉnh tự động hiện ra cửa số “output” của Visual Studio – cho phép chúng ta theo dõi hành động đệ quy của ứng dụng

Bạn có thể lựa chọn wire-up lắng nghe theo dõi tùy chỉnh trong ứng dụng của bạn – trong trường hợp này các thông báo bạn in từ TracePoints sẽ được dẫn ra thay vì cửa sổ đầu ra VS

TracePoint – Running a Custom Macro (Chạy như 1 Custom Macro)

Trong 1 bài nói chuyện tôi đã đưa ra lần trước ở London, 1 vài khán giả yêu cầu liệu nó có thể tự động xuất ra tất cả các biến cụ bộ khi 1 TracePoint được nhấn

Khả năng này không được xây dựng trong Visual Studio – nhưng có thể kích hoạt bằng cách viết 1 Macro(macro là một chương trình con được viết sẵn theo một mục đích nào đó, để thi hành một lệnh , một công việc nào đó theo nguyện vọng của người lập trình) tùy chỉnh trong Visual Studio, và sau đó dẫn 1 TracePoint để gọi đến Macro khi nó được nhận ra. Để kích hoạt điều này, mở Macros IDE trong Visual Studio (Tools->Macros->Macros IDE menu command). Sau đó dưới nút MyMacros của project, chọn 1 module hoặc tạo cái mới (ví dụ: thêm 1 tên là (“UsefulThings”)). Sau đó paste code macro VB sau đây vào module và lưu nó:

Sub DumpLocals()

Dim outputWindow As EnvDTE.OutputWindow

outputWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutpu.Object

Dim currentStackFrame As EnvDTE.StackFrame

currentStackFrame = DTE.Debugger.CurrentStackFrame

outputWindow.ActivePane.OutputString(“*Dumping Local Variables*” + vbCrLf)

For Each exp As EnvDTE.Expression In currentStackFrame.Locals

outputWindow.ActivePane.OutputString(exp.Name + ” = “ +exp.Value.ToString() + vbCrLf)

Next

End Sub

Trên đoạn vòng lặp code macro thông qua cụm cấu trúc hiện tại và kiết xuất tất cả biến cục bộ lên cửa sổ đầu ra

Sử dụng DumpLocals Custom Macro

Chúng ta có thể tận dụng lợi thế của macro “DumpLocals” tùy chỉnh bằng cách sử dụng ứng dụng bổ sung đơn giản dưới đây:

Chúng ta sẽ sử dụng F9 để đặt 1 breakpoint trên câu lệnh trả về trong phương thức “Add” ở trên. Sau đó click chuột phải trên breakpoint và chọn lệnh “When hit”

Sẽ có 1 hộp thoại bên dưới. Không như trước nơi mà chúng ta sử dụng hộp lựa chọn “In ra 1 thông báo”(print a message) và quy định bằng tay các biến mà muốn hiển thị đầu ra, lúc này thay vì chọn “Run a macro” và trỏ đến UsefulThings tùy chỉnh. Macro DumpLocals tạo bên dưới:

Chúng ta sẽ giữ hộp đánh dấu “continue execution” để chương trình tiếp tục chạy thậm chí khi TractPoints được nhấn

Runing a Application (chạy 1 ứng dụng)

Bây giờ khi nhấn F5 và chạy ứng dụng, ta sẽ nhìn thầy đầu ra hiện bên dưới trong cửa sổ “output” của Visual Studio khi phương thức Add được gọi. Lưu ý cách mà macro tự động liệt kê tên và giá trị của mỗi biến cục bộ khi TracePoint được nhấn:

Tóm tắt

Chương trình debug Visual Studio vô cùng phong phú. Tôi khuyên bạn nên dành thời gian để thực sự tìm hiểu tất cả các tính năng của nó. Mẹo và thủ thuật ở trên chỉ là một vài trong rất nhiều tính năng nó cung cấp mà hầu hết mọi người không biết.

Using LINQ to ADO.NET Entity Data Model

Add a new ADO.NET Data Model.

Common Linq To Ado Net 010

Using the ADO.NET Entity Framework wizard you can easily create a representation of the sample Northwind database like the one below:

Common Linq To Ado Net 020

Collapse imageQuery an Entity from the Database

The next code-snippet uses LINQ query syntax to retreive an IEnumerable sequence of Product objects.

CopyC#
NorthwindEntities dbContext = new NorthwindEntities();
var query = from p in dbContext.ProductSet
            where p.Categories.CategoryName == "Seafood"
            select p;
IEnumerable<Product> products = query.ToList();
CopyVB.NET
Dim dbContext As New NorthwindEntities()
Dim query = From p In dbContext.ProductSet _
    Where p.Categories.CategoryName = "Seafood" _
    Select p
Dim products As IEnumerable(Of Product) = query.ToList()

Collapse imageUpdate an Entity in the Database

The code below demonstrates how to grab a single Product object from the database, update its price, and then save the changes back to the database.

CopyC#
NorthwindEntities dbContext = new NorthwindEntities();
Product product = dbContext.ProductSet.Single( p => p.ProductName == "Aniseed Syrup" );
product.UnitPrice = 1000;
dbContext.SaveChanges();
CopyVB.NET
Dim dbContext As New NorthwindEntities()
Dim query = From p In dbContext.ProductSet_
            Where p.ProductName = "Aniseed Syrup" _
            Select p
product.UnitPrice = 1000
dbContext.SaveChanges()

Collapse imageInsert a New Record(s) in the Database

The code below shows you how to create a new Category object. Then how to create two new Products and associate them with the Category. Finally, all three objects are saved in the database.

CopyC#
NorthwindEntities dbContext = new NorthwindEntities();

Category category = new Category();
category.CategoryName = "Test Category";

Product firstProduct = new Product();
firstProduct.ProductName = "Test Product 1";

Product secondProduct = new Product();
secondProduct.ProductName = "Test Product 2";

category.Products.Add( firstProduct );
category.Products.Add( secondProduct );

dbContext.AddToCategorySet( category );
dbContext.SaveChanges();
CopyVB.NET
Dim dbContext As New NorthwindEntities()

Dim category As New Category()
category.CategoryName = "Test Category"

Dim firstProduct As New Product()
firstProduct.ProductName = "Test Product 1"

Dim secondProduct As New Product()
secondProduct.ProductName = "Test Product 2"

category.Products.Add(firstProduct)
category.Products.Add(secondProduct)

dbContext.AddToCategorySet(category)
dbContext.SaveChanges()

Collapse imageDelete a Record from the Database

The code below demonstrates you how to delete all “Test” products from the database.

CopyC#
NorthwindEntities dbContext = new NorthwindEntities();
var query = from p in dbContext.ProductSet
            where p.ProductName.Contains( "Test" )
            select p;
foreach ( Product p in query )
    dbContext.DeleteObject( p );
dbContext.SaveChanges();
CopyVB.NET
Dim dbContext As New NorthwindEntities()
Dim query = From p In dbContext.ProductSet _
    Where p.ProductName.Contains("Test") _
    Select p
For Each p As Product In query
    dbContext.DeleteObject(p)
Next
dbContext.SaveChanges()

Collapse imageRetreive a Record with Server Side Paging

The next example shows you how to implement efficient server-side database paging. By using the Skip() and Take() methods, you will return 15 rows from the database – starting with row 300.

CopyC#
NorthwindEntities dbContext = new NorthwindEntities();
var query = ( from p in dbContext.ProductSet
              where p.Categories.CategoryName == "Aniseed Syrup"
              select p ).Skip( 300 ).Take( 15 );
IEnumerable<Product> products = query.ToList();
CopyVB.NET
Dim dbContext As New NorthwindEntities()
Dim query = (From p In dbContext.ProductSet _
    Where p.Categories.CategoryName = "Aniseed Syrup" _
    Select p).Skip(300).Take(15)
Dim products As IEnumerable(Of Product) = query.ToList()

So sánh LINQ to SQL và ADO.NET Entity Framework

LINQ to SQL và Entity Framework có rất nhiều điểm chung, nhưng mỗi cái có những đặc tính riêng nhắm đến những trường hợp khác nhau trong Orcas (bản VS 2008).

 

LINQ to SQL có các đặc tính hướng đến việc phát triển nhanh ứng dụng với CSDL Microsoft SQL Server. LINQ to SQL cho phép bạn có một cái nhìn chặt chẽ về kiểu với cấu trúc của CSDL của bạn. LINQ to SQL hỗ trợ việc ánh xạ 1-1 trực tiếp cấu trúc dữ liệu của bạn vào các lớp; một bảng đơn có thể được ánh xạ vào một cấu trúc phân cấp (ví dụ một bảng có thể chứa person, customer và employee) và các khóa ngoài có thể ánh xạ thành các quan hệ strongly-typed. Bạn có thể thực hiện truy vấn trên các các bảng, các view hay thậm chí các kết quả dạng bảng trả về bởi một function thông qua các phương thức. Một trong những mục tiêu thiết kế chính của LINQ to SQL là nhằm làm cho nó có thể dùng được ngay đối với những trường hợp thông thường; vậy nên, ví dụ bạn truy cập một tập các order thông qua thuộc tính Orders của một customer, và các order của customer đó chưa được đọc vào, LINQ to SQL sẽ tự động đọc vào từ CSDL cho bạn. LINQ to SQL dựa trên những quy ước cho trước, bạn có thể dựa trên các quy ước này để tùy biến, chẳng hạn như thay đổi các thao tác mặc nhiên cho việc insert, update và delete bằng cách tạo ra những câu lệnh thao tác với CSDL (ví dụ “InsertCustomer”, “UpdateCustomer”, “DeleteCustomer”). Các phương thức này có thể gọi các thủ tục trong CSDL hay thực hiện thêm các thao tác để xử lý các thay đổi.

Entity Framework có các đặc tính nhắm đến các ứng dụng doanh nghiệp (“Enterprise Scenarios”). Trong một doanh nghiệp, một CSDL thông thường được kiểm soát bởi DBA (người quản trị CSDL), cấu trúc của CSDL thông thường được tối ưu cho việc lưu trữ (hiệu năng, tính toàn vẹn, phân hoạch) hơn là cho một mô hình ứng dụng tốt, và có thể thay đổi qua thời gian khi dữ liệu và việc sử dụng phát triển lên. Với ý tưởng này, Entity Framework được thiết kế xung quanh việc xây dựng một mô hình dữ liệu hướng tới ứng dụng, ít phụ thuộc, thậm chí có thể khác một chút so với cấu trúc CSDL thực sự. Ví dụ, bạn có thể ánh xạ một lớp đơn (hay “thực thể”) và nhiều table/view, hay ánh xạ nhiều lớp vào cùng một table/view. Bạn có thể ánh xạ vào một cấu trúc phân cấp vào một table/view đơn (như trong LINQ to SQL) hay vào nhiều table/view (ví dụ: person, customer, employee có thể nằm trong các bảng riêng biệt vì customer và employee chỉ chứa thêm một số thông tin không có trong person, hoặc lặp lại các cột từ bảng person). Bạn có thể nhóm các thuộc tính vào các kiểu phức hợp (“complex”, hay “composite”), ví dụ một kiểu Customer có thể có thuộc tính “Address” với kiểu Address có các thuộc tính Street, City, Region, Country và Postal). Entity Framework cũng cho phép bạn biểu diễn quan hệ nhiều-nhiều một cách trực tiếp, mà không cần tới bảng kết nối như một thực thể trong mô hình dữ liệu, và có một đặc tính mới được gọi là “Defining Query”, có thể được dùng cho việc biểu diễn một bảng ảo với dữ liệu lấy từ một câu truy vấn (ngoài trừ việc cập nhật phải thông qua một stored procedure). Khả năng ánh xạ mềm dẻo này, bao gồm tùy chọn dùng các stored procedure để xử lý các thay đổi, có thể được thực hiện chỉ bằng cách khai báo, hoặc chỉnh sửa lại khi yêu cầu thay đổi, mà không cần phải biên dịch lại ứng dụng.

Entity Framework bao gồm LINQ to Entities đưa ra nhiều tính năng giống với LINQ to SQL trên mô hình ứng dụng ở mức khái niệm; bạn có thể xây dựng các câu truy vấn trong LINQ (hay trong “entity SQL”, một phiên bản mở rộng của SQL để hỗ trợ các khái niệm như strong-typing, đa hình, kiểu phức hợp…) trả về kết quả ở dạng các đối tượng CLR, thực thi các thủ tục hay các hàm trả về kiểu bảng thông qua các phương thức, và cho phép gọi một phương thức để lưu lại các thay đổi.

Tuy nhiên, Entity Framwork còn hơn cả LINQ to Entities; nó bao gồm một lớp lưu trữ cho phép bạn dùng cùng mô hình ứng dụng mức khái niệm thông qua giao diện ADO.NET ở mức thấp dùng Entity SQL, và trả lại kết quả một cách hiệu quả nhờ các DataReader, giảm thiểu tải khi dùng trong các ngữ cảnh chỉ có đọc và không có các xử lý thêm.

Vậy nên, trong khi có nhiều phần bị trùng lắp, LINQ to SQL được nhắm đến việc phát triển nhanh ứng dụng cùng SQL Server, còn Entity Framework cung cấp các lớp truy xuất đối tượng và lưu trữ dữ liệu cho Microsoft SQL Server cũng như các CSDL khác thông qua khả năng ánh xạ mềm dẻo và ít phụ thuộc vào cấu trúc của CSDL.Tôi biết điều này dễ gây nhầm lẫn, và chúng tôi đang cố gắng tìm cách mô tả những điểm khác nhau đó nhằm giúp khách hàng có thể lựa chọn một cách đúng đắn. Xin hãy cho tôi biết nếu bài viết này có thể giúp ích cho bạn, hoặc còn điều gì chưa rõ ràng…

Thanks,

Michael Pizzo

Principal Architect

Microsoft Data Programmability

Người dịch: Bài viết này được dịch lại từ http://namdh.wordpress.com/2010/04/22/linq-to-sql-vs-ado-net-entity-framework/, và nội dung gốc của bài này được sao chép từ http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/dc83097e-9c70-4970-93e2-dbc8636eb321/.