LINQ – Giới thiệu về LINQ to Objects
(DongND – Phòng nghiên cứu và phát triển sản phẩm, Fast Software)
Mục lục
1. Giới thiệu về LINQ
2. LINQ to Objects
Lý thuyết chung về LINQ
Một ví dụ đơn giản
Một ví dụ phức tạp hơn
3. Một ứng dụng thực tế
1. Giới thiệu về LINQ
LINQ (có thể đọc là “LIN – Q”) là cụm từ viết tắt của Language Integrated Query, tạm dịch là “ngôn ngữ tích hợp truy vấn”. Sinh ra với ý tưởng chính là làm sao có thể tích hợp được các câu truy vấn dữ liệu vào bản thân các ngôn ngữ lập trình mà không cần quan tâm dữ liệu nguồn lấy từ đâu và kiểu dữ liệu là gì.
LINQ mô tả một tập hợp các toán tử sử dụng để truy vấn, lọc dữ liệu trong các dữ liệu nguồn như mảng, các lớp kiểu liệt kê (enumerable class), XML, CSDL quan hệ và các nguồn dữ liệu của các hãng thứ ba khác.
Để mọi nguồn dữ liệu có thể truy vấn, LINQ yêu cầu dữ liệu có thể được đóng gói (encapsulated) như là objects. Những câu truy vấn sẽ được xử lý bởi bộ máy xử lý LINQ hoặc thông qua một bộ máy mở rộng có dùng provider của LINQ. Câu truy vấn có thể tự động chuyển đổi thành các dạng khác nhau trước khi thực thi như chúng có thể đổi thành các câu lệnh SQL khi thực thi trên database server. Kết quả truy vấn được sẽ trả về bộ nhớ RAM của máy tính và có thể được duyệt bới các hàm foreach trong các ngôn ngữ lập trình.
Các thành phần chính của LINQ bao gồm LINQ to XML, LINQ to Objects, LINQ to ADO.NET, LINQ to SQL, … Các thành phần được chia ra thường được dựa vào nguồn dữ liệu của chúng. Ví dụ Linq to Google (Glinq) được dùng để truy cập nguồn dữ liệu của Google.
LINQ được phát hành như là một phần của .Net Framework 3.5, bộ Framework này được tung ra vào 19/11/2007 bởi Microsoft.
2. LINQ to Objects
Lý thuyết chung về LINQ
Để truy vấn dữ liệu trong LINQ, yêu cầu chúng ta phải thực hiện 3 bước chính. Bước 1 phải xác định được dữ liệu nguồn, bước 2 là viết câu truy vấn và bước 3 là thực hiện câu truy vấn đó.
Các toán tử thông dụng của LINQ bao gồm: Where, Sum / Min / Max / Average / Aggregate, Join / GroupJoin , Take / TakeWhile, Skip / SkipWhile, OrderBy / ThenBy, Concat, GroupBy, Union / Intersect / Except , Distinct, EqualAll, Any / All / Contains, Count.... Các toán thử thường có ý nghĩa tương tự như các câu truy vấn trong SQL.
Privider LINQ to Objects thường được sử dụng để truy vấn các mảng dữ liệu trong bộ nhớ của máy tính mà không cần dùng đến các provider để kết nối với các chương trình khác như SQL provider. Code được sinh ra dựa trên kiểu của lớp (có thực thi giao lớp diện Ienumerable, có nghĩa là ở dạng danh sách có thể liệt kê được)
Một ví dụ đơn giản
Truy vấn trong mảng kiểu Int. Ta có một mảng kiểu int chứa các phần tử cho sẵn, dùng LINQ để lấy ra các phần tử là số chẵn.
---------------------------------------- code 01 below ---------------------------
Code:
Private Shared Sub Main()
'1. Dữ liệu nguồn
Dim numbers As Integer() = New Integer(6) {0, 1, 2, 3, 4, 5, 6}
' 2. Tạo câu truy vấn, lấy các phần tử là số chẵn
Dim numQuery = From num In numbers _
Where (num Mod 2) = 0 _
Select num
' 3. Thực thi câu truy vấn
For Each num As Integer In numQuery
Console.Write("{0,1} ", num)
Next
End Sub
----------------------------------------end code 01-------------------------------
Một ví dụ phức tạp hơn
Truy vấn trong các lớp tự tạo. Ví dụ ta có 2 lớp “ct00” và “dmkh”, chúng quan hệ với nhau nhờ thuộc tính “ma_kh”.
Ví dụ yêu cầu liệt kê các phát sinh trong ct00, có left join với dmkh để lấy tên khách, tài khoản kế toán, phát sinh nợ, phát sinh có với điều kiện ma_kh=”KH00001”. Sắp xếp kết quả theo mã khách hàng, tài khoản.
Code:
---------------------------------------- code 02 below ---------------------------
Dim query = From p In listct00 Group Join r In listdmkh On p.ma_kh Equals r.ma_kh _
Into Group From r In Group.DefaultIfEmpty() _
Select p.tk, p.tk_du, p.ma_kh, p.ps_no, p.ps_co, ten_kh = If(r Is Nothing, "[Không có tên]", r.ten_kh) Order By ma_kh, tk 'Where ma_kh = "KH00001"
For Each item In query
Me.TextBox1.Text += "ma_kh: " + item.ma_kh + ", ten_kh: " + item.ten_kh + ", tk: " + item.tk + ", tk_du: " + item.tk_du + ", ps_no: " + item.ps_no.ToString + ", ps_co:" + item.ps_co.ToString + vbCrLf
Next
----------------------------------------end code 02-------------------------------
3. Một ứng dụng thực tế
Một ví về một ứng dụng nhỏ MyFolderInfo (năm 2008) của cùng một tác giả bài viết. Chức năng chính của ứng dụng này là đọc cấu trúc thư mục Windows sau đó hiển thị lên một treeview và lưu xuống 1 file xml để quản lý sự thay đổi của chúng. Nhưng khi hiển thị lên treeview không thể cho nó hiện một lúc tất cả các thư mục cha, thư mục con, tập tin... Vậy ta chỉ load thư mục và tập tin con cấp 1 và cấp 2 của thư mục cha được click vào. Ta có thể làm như sau:
+ Bước 1: Kiểm tra xem đã có thư mục con cấp 2 trên cây? Nếu có thì kết thúc công việc.
+ Bước 2: Kiểm tra xem có thư mục con cấp 1 trên cây? Nếu có thì thêm thư mục con cấp 2. Nếu không có thì thêm cả thư mục cấp 1 và cấp 2.
Để thêm các thư mục con thì ta làm như sau:
++ SELECT các thư mục từ dữ liệu nguồn
++ WHERE treenode.tag chứa giá trị là node cha của các node (thư mục) được load về.
+ Bước 3: Tạo danh sách các node từ kết quả trả về, gắn lên treeview.
Kết thúc công việc.
Cách viết trong LINQ rất tự nhiên, hiện có hai cách chính đó là Lambda Expression và Query Expression. Lambda thì dùng các ký hiệu cổ xưa của Hy Lạp để biểu diễn khá giống toán học, nhưng cũng khá dễ và rất may là chúng ta không cần phải học thêm tiếng Hy Lạp. Còn Query Expression thì quá quen thuộc đối với các nhà phát triển ứng dụng có cơ sở dữ liệu, chúng khá giống với các câu lệnh SQL.
Ta thấy rằng, LINQ đã mở ra những hướng mới trong việc xử lý, truy vấn dữ liệu từ nhiều nguồn khác nhau. LINQ ngày càng phổ biến do những ưu điểm của nó cũng như là công nghệ mới nhất trong lập trình hiện nay.
Ghi chú
- Bài viết có sử dụng nguồn tham khảo: Wiki, tại đại chỉ
http://en.wikipedia.org/wiki/Language_Integrated_Query
- Bài viết có đính kèm code sample bên dưới. (contact DongMT for more detail)
Bổ sung: LinQ có thể ứng dụng rất tốt trong trường hợp cho chính người dùng tạo database mà không cần biết mối quan hệ và lọa database nào ! mà nè! bên FRD định spam fast à?
Trả lờiXóaNày, bài viết hàng quí nhé. hihi
Trả lờiXóaCó bao giờ nghe tới SubSonic chưa? Hãy thử và cảm nhận đi. www.subsonicproject.com
Trả lờiXóa