Thứ Sáu, 27 tháng 4, 2012

Deferred Execution trong LINQ

Trong LINQ, có một cơ chế giúp tối ưu hóa việc truy xuất dữ liệu đó là cơ chế Deferred Execution. Cơ chế này sẽ giúp trì hoãn việc truy xuất dữ liệu, dữ liệu chỉ được truy xuất khi bạn thật sự làm việc với nó. Ơ bài viết này, tôi không tập trung phân tích về Deferred Execution, nếu bạn muốn đọc về vấn đề này thì hãy vào đây http://blogs.msdn.com/charlie/archive/2007/12/09/deferred-execution.aspx Trong bài viết này, tôi chỉ đưa ra 2 minh họa để cho thấy được hoạt động thật sự Deferred Execution. Để chuẩn bị, tôi có một đoạn chương trình nhỏ như sau:
Đoạn chương trình này sẽ truy xuất đến một Cơ sở dữ liệu SQL Server có sẵn của tôi. Các bước của chương trình bao gồm: 1. Tạo truy vấn dữ liệu bằng LINQ to SQL 2. Tạm dừng, chờ nhấn 1 phím bất kỳ 3. Duyệt qua tất cả các record thu được, với mỗi record tôi sẽ cho chương trình nghỉ 1000 ms (ở đây tôi giả lập thời gian thực hiện của chương trình) Minh họa thứ 1: Tôi sẽ có 1 break point ở dòng lệnh Console.ReadKey() đầu tiên để debug xem kết quả của TestQuery là gì Và đây là kết quả tôi thu được:
Lúc này, TestQuery của tôi chỉ mang giá trị là “{SELECT [t0].[QuestionID], [t0].[Content], [t0].[QuestionA], [t0].[QuestionB], [t0].[QuestionC], [t0].[QuestionD], [t0].[Answer] FROM [dbo].[Question] AS [t0]}” Như vậy, TestQuery của tôi chỉ mang giá trị là một câu truy vấn được tạo thành từ code của tôi. Minh họa thứ 2: Liệu có thật sự là như thế không? Hay đây chỉ là 1 thể hiện của Debug? Lần này, tôi sẽ monitor những kết nối đến SQL Server trực tiếp ở Database Server của tôi. Tôi sẽ remove tất cả các break point, đóng tất cả các kết nối bên ngoài đang kết nối đến SQL Server của tôi. Tôi chạy chương trình:
Như các bạn thấy, tôi chạy chương trình và chương trình của tôi đã dừng lại ở dòng Console.ReadKey() đầu tiên, điều này có nghĩa là chương trình của tôi đã đi qua bước khởi tạo đối tượng DataContext và tạo truy vấn TestQuery. Tôi chuyển sang màn hình Monitor Activity ở SQL Server để xem như thế nào
Rõ ràng là nhìn vào màn hình Monitor Activity ở SQL Server, tôi không hề thấy việc truy xuất dữ liệu từ chương trình của tôi mặc dù chương trình đã đi qua việc tạo nên đối tượng DataContext cũng như hoàn tất việc tạo TestQuery. Tiếp tục, tôi cho chương trình ban đầu của tôi chạy tiếp bằng cách ấn 1 phím bất kỳ, và hãy xem kết quả thu được như thế nào. (Các bạn nên nhớ rằng tôi đã cô lập toàn bộ các kết nối SQL Server của tôi) Chương trình chạy:
Monitor Activity ở SQL Server:
Như vậy là tôi đã kiểm tra thực tế được cơ chế Deferred Execution của LINQ thông qua 2 minh họa khá đơn giản bên trên. Các bạn cũng có thể dựa vào đây để tự tạo ra các minh họa cho mình chẳng hạn: tạo ra 1 collection có thể fire 1 event khi truy xuất các phần tử rồi kiểm tra cơ chế này (LINQ to Object) hoặc truy xuất đến 1 file XML và xem thử khi nào thì file này thật sự bị truy xuất (LINQ to XML)

Không có nhận xét nào: