LINQ là gì
1. LINQ là gì ?
Để giảm gánh nặng thao tác trên nhiều ngôn ngữ khác nhau và cải
thiện năng suất lập trình, Microsoft đã phát triển giải pháp tích
hợp dữ liệu cho .NET Framework có tên gọi là LINQ (Language Integrated
Query), đây là thư viện mở rộng cho các ngôn ngữ lập trình C# và
Visual Basic.NET (có thể mở rộng cho các ngôn ngữ khác) cung cấp khả
năng truy vấn trực tiếp dữ liệu Object, CSDL và XML.
LINQ là một tập hợp các thành phần mở rộng cho phép viết các câu truy
vấn dữ liệu ngay trong một ngôn ngữ lập trình, như C# hoặc VB.NET.
LINQ là từ viết tắt của
“Language-Integrated Query”
2. Tôi cần có gì để lập trình LINQ ?
LINQ có từ bản .NET 3.5, vậy nên tối thiểu chương trình của bạn phải chạy trên nền tảng này.
Visual Studio 2008, hoặc các phiên bản Express của nó là các bộ công cụ phát triển tiêu biểu cho ứng dụng dùng LINQ.
Tải về Visual Studio 2008
tại đây.
Tải về Visual Studio Express
tại đây.
3. LINQ và ADO.NET khác nhau chỗ nào ?
Nôm na, LINQ là tập mở rộng cho phép viết các câu truy vấn ngay trong
các ngôn ngữ lập trình. Nó cho phép bạn làm việc với các kiểu tập hợp
dữ liệu, như XML, collection, array,… và cả CSDL.
ADO.NET là công nghệ cho phép các ứng dụng có thể kết nối và làm việc
với các loại CSDL khác nhau (truy vấn, cập nhật, thêm, xóa, gọi thủ
tục…).
Bản thân LINQ không phải là một công nghệ được tạo ra để thay thế
ADO.NET, bạn có thể làm việc với LINQ mà không dính gì đến CSDL. Tuy
nhiên, LINQ to SQL, là một phần mở rộng của LINQ, cho phép bạn có thể
làm việc được với CSDL SQL Server, trong trường hợp này thì khi viết bạn
có thể bỏ qua các câu lệnh ADO.NET mà chỉ quan tâm tới cú pháp mà LINQ
cung cấp.
Nhớ rằng dù bạn không hề dùng đến ADO.NET khi viết chương trình
sử dụng LINQ to SQL, nhưng đằng sau nó, ADO.NET vẫn được dùng để thực
hiện kết nối, gửi các câu lệnh, các lời gọi thủ tục…
4. LINQ có hỗ trợ Unicode không ?
Có, LINQ là một thành phần của .NET, và như vậy, LINQ hỗ trợ Unicode
một cách hoàn toàn tự nhiên, bạn có thể làm các thao tác chèn, sửa dữ
liệu với tiếng Việt mà không cần cấu hình thêm. Tất nhiên, khi thiết kế
CSDL, bạn vẫn phải chọn kiểu dữ liệu (NVARCHAR) và collation phù hợp để
LINQ có thể làm việc một cách đúng đắn.
5. Tôi không thể tìm thấy một số phương thức (Add, RemoveAll…) như các ví dụ trong loạt bài “LINQ to SQL”
Kể từ bản RTM, các phương thức dùng cho thêm và xóa entity đã được đổi tên, cụ thể như sau:
- Add đổi thành InsertOnSubmit
- AddAll đổi thành InsertAllOnSubmit
- Remove đổi thành DeleteOnSubmit
- RemoveAll đổi thành DeleteAllOnSubmit
6. SQL và LINQ khác nhau thế nào?
SQL chỉ được dùng để truy vấn dữ liệu trong các CSDL dạng quan hệ,
nếu muốn truy cập các dạng dữ liệu khác như HTML, XML v.v… thì đây là
điều không thể đối với SQL và có thể đối với LINQ. Do đó có thể nói đây
là 1 ưu điểm khác của LINQ mà SQL không có.
Ưa điểm của LINQ
Trước hết: tôi xin nói về quy luật cơ bản trong lập
trình là dữ liệu phải nằm trong bộ nhớ chính. Do đó khi cần dữ liệu
chúng ta phải dùng cách nào đó để đưa dữ liệu vào bộ nhớ (đọc text file,
truy vấn từ database …). Trong môi trường .NET, dữ liệu trong bộ nhớ
thường được thể hiện ở dạng các đối tượng và trước LINQ, chúng ta không
có cách nào để móc nối các đối tượng hay thực hiện bất kỳ thao tác truy
vấn nào. LINQ chính là giải pháp cho vấn đề này.
Thứ 2: Trước đây, cách phổ biến nhất để ứng dụng lấy
dữ liệu từ các hệ cơ sở dữ liệu (CSDL) là sử dụng SQL (Structure Query
Language – ngôn ngữ truy vấn cấu trúc). SQL có cú pháp rất khác với
những ngôn ngữ lập trình phổ dụng như C# và VB.NET, do vậy bạn phải nhọc
công “hàn gắn” hai thực thể khác biệt này với nhau trong mỗi dự án phần
mềm. LINQ ra đời để giảm gánh nặng thao tác “hàn gắn” trên nhiều ngôn
ngữ khác nhau.
Thứ 3: Một vấn đề khác với SQL là nó chỉ dùng để
truy vấn dữ liệu trong các CSDL dạng quan hệ. Nếu muốn truy cập dữ liệu
XML hay dạng khác (như trang HTML, email…), bạn lại phải sử dụng cú pháp
truy vấn khác (XPath/XQuery). Cách giải quyết vấn đề tốt nhất hiện nay
là LINQ
Thứ 4: Về vấn đề “Error” chúng ta không lập trình
tương tác với CSDL tại cấp độ native language. Vì thế lỗi thường khó
phát hiện rõ. Khó khăn trong việc quản lý lỗi xảy ra.
Thứ 5: Về vấn đề cú pháp truy vấn thì trước khi có
LINQ chúng ta chưa có 1 cú pháp chung nào cho truy vấn dữ liệu từ những
nguồn khác nhau. Với LINQ nó sẽ cung cấp cách duy nhất để truy cập dữ
liệu từ bất kể nguồn dữ liệu nào với cú pháp giống nhau. Ngoài ra cách
viết dễ dàng cho việc đọc và phân tích. Trường hợp này sẽ được thể hiện
rõ ràng khi chúng ta cần lọc những dữ liệu với nhiều điều kiện phân cấp
khác nhau thì LINQ sẽ thể hiện rõ tính ưu việt của mình. LINQ cũng cung
cấp những bộ lọc, sắp xếp thứ tự, nhóm dữ liệu với khối lượng code tối
thiểu nhưng vẫn bảo đảm tính rõ ràng.
7. Truy vấn LINQ
LINQ hỗ trợ loại dữ liệu IEnumerable <T>. Những đối tượng hỗ
trợ IEnumerable <T> và IQueryable(T) được gọi là queryable.
3 phần của biểu thức LINQ
1. Có được các dữ liệu nguồn.
2. Tạo các truy vấn.
3. Thực hiện các truy vấn.
Ví dụ trong mã nguồn sau đây cho thấy ba phần của một truy vấn hoạt động như thế nào.
class IntroToLINQ
{
static void Main()
{
// The Three Parts of a LINQ Query:
// 1. Data source.
int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
// 2. Query creation.
// numQuery is an IEnumerable
var numQuery = from num in numbers
where (num % 2) == 0
select num;
// 3. Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
}
}
Minh họa sau đây cho thấy các hoạt động truy vấn. Trong LINQ việc
thực hiện các truy vấn được thực hiện khi bạn truy cập dữ liệu.
Các nguồn dữ liệu.
Trong ví dụ trước vì dữ liệu là một mảng, nó hoàn toàn hỗ trợ đặc điểm
chung giao diện IEnumerable <T>. Điều này có nghĩa thực tế nó có
thể được truy vấn với LINQ. Một truy vấn được thực hiện trong một câu
lệnh foreach và foreach yêu cầu hỗ trợ IEnumerable hay IEnumerable(T).
Loại có hỗ trợ IEnumerable(T) hoặc IQueryable(T) được gọi là queryable.
Với LINQ to SQL, trước tiên bạn tạo một đối tượng quan hệ được ánh xạ
vào lúc thiết kế bằng cách sử dụng trình thiết kế đối tượng quan hệ
(O/R Designer) hoặc tự viết code. Viết các câu truy vấn dựa trên đối
tượng và thi hành để LINQ to SQL xử lý việc giao tiếp với cơ sở dữ
liệu. Trong ví dụ sau, Customer đại diện cho một bảng trong cơ sở dữ
liệu, và Table<Customer> hỗ trợ các đặc tính chung
IQueryable<T>.
// Create a data source from a SQL Server database.
// using System.Data.Linq;
DataContext db = new DataContext(@"c:\northwind\northwnd.mdf");
Truy vấn.
Truy vấn trong ví dụ trước trả về tất cả các số từ mảng số nguyên. Các
biểu thức truy vấn chứa ba mệnh đề: from, where, select. (Nếu bạn đang
quen với SQL sắp đặt của các mệnh đề là sai vị trí trong SQL). Mệnh đề
from dùng để xác định nguồn dữ liệu, mệnh đề where dùng để lọc dữ liệu,
mệnh đề select dùng để chọn ra những phần tử được trả về. Lúc này một
điểm quan trọng là trong LINQ, các biến truy vấn chỉ chứa đựng thông
tin truy vấn, là yêu cầu kết quả trả về khi câu truy vấn được thực hiện
chứ nó không thực hiện việc truy vấn dữ liệu.
Thực thi truy vấn:
Cũng giống như trạng thái trước đây, biến truy vấn tự nó chỉ chứa
các lệnh truy vấn. Việc truy vấn dữ liệu chỉ được thực hiện khi bạn
truy cập đến dữ liệu trả về từ câu truy vấn:
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
Câu lệnh foreach là nơi các kết quả truy vấn được trả về. Bởi các
biến truy vấn tự nó không bao giờ chứa kết quả truy vấn, bạn có thể sử
dụng lại nó để bổ sung hoặc thực thi lấy dữ liệu tại một nơi khác.
8. Tách rời DataContext và các lớp thực thể vào các namespaces khác nhau
O / R Designer cung cấp cho các thuộc tính Context Namespace và Entity
Namespace trên DataContext. Những thuộc tính này xác định tên của lớp
DataContext và lớp các thực thể đã được tạo ra. Theo mặc định, các
thuộc tính là rỗng, lớp DataContext và các lớp thực thể được đưa vào
cùng một namesapce. Để đưa các lớp vào các namespace khác nhau, chúng ta
có thể nhập giá trị vào trong thuộc tính Context Namespace và / hoặc
Entity Namespace.