LINQ – Language Integrated Query (ngôn ngữ truy vấn tích hợp) là một phương pháp truy vấn dữ liệu từ một tập hợp dữ liệu. Trong bài viết này, chúng ta sẽ tìm hiểu về LINQ và cách nó hoạt động.
Dữ liệu trong lập trình
Trong lập trình, việc làm việc với dữ liệu là điều không thể tránh khỏi. Dữ liệu có thể xuất phát từ nhiều nguồn khác nhau như bộ nhớ, XML, cơ sở dữ liệu (Mysql, Sql Server) và các nguồn lưu trữ khác. Dù dữ liệu đến từ đâu, chúng ta luôn cần truy vấn dữ liệu. Tuy nhiên, với mỗi nguồn dữ liệu khác nhau, cách thực hiện truy vấn cũng khác nhau.
Ví dụ:
- Nếu chúng ta có một danh sách được lưu trong bộ nhớ, chúng ta có thể sử dụng vòng lặp
for
,foreach
kết hợp với các biểu thức so sánh để truy vấn dữ liệu. - Nếu chúng ta có dữ liệu trong file XML, chúng ta phải truy vấn từng node để có được các bản ghi hợp lệ.
- Nếu chúng ta có dữ liệu trong cơ sở dữ liệu, chúng ta phải thực hiện truy vấn trong bảng và trả về các bản ghi hợp lệ.
- …
Đó là lý do tại sao các kỹ sư Microsoft đã thực hiện hợp nhất các cách truy vấn thành một để có thể dùng chung cho các nguồn dữ liệu khác nhau. LINQ ra đời và được thêm vào phiên bản .NET 3.5.
Các thành phần của LINQ
LINQ gồm các thành phần sau:
- Nguồn dữ liệu: LINQ cung cấp các providers khác nhau để truy vấn đến các nguồn dữ liệu khác nhau. Các providers bao gồm LINQ to Objects, LINQ to SQL, LINQ to Entities, LINQ to DataSets, và LINQ to XML.
- Câu lệnh truy vấn: Để truy vấn dữ liệu, chúng ta có thể sử dụng cú pháp truy vấn hoặc cú pháp phương thức.
- Thực thi truy vấn để lấy kết quả.
1. Nguồn dữ liệu
LINQ cung cấp các providers khác nhau để truy vấn đến các nguồn dữ liệu khác nhau. Dưới đây là danh sách các providers và giải thích:
- LINQ to Objects: Sử dụng LINQ đối với các đối tượng collection implement từ IEnumerable hoặc IEnumerable (dữ liệu được lưu trong bộ nhớ). Đây là provider được sử dụng rộng rãi đặc biệt cho những bài toán cần hiệu năng cao.
- LINQ to SQL: Thực hiện map các tables, views, store procedures thành các đối tượng. LINQ sẽ thực hiện truy vấn trên các đối tượng đó bằng cách chuyển đổi qua lại giữa đối tượng và câu lệnh SQL. Ngoài ra, còn hỗ trợ thêm/sửa/xóa dữ liệu dựa trên các đối tượng trên. Được sử dụng khá nhiều trong thực tế dưới tên Entity Framework hoặc Entity Framework Core. Tuy nhiên, chỉ làm việc với cơ sở dữ liệu SQL Server.
- LINQ to Entities: Tương tự như LINQ to SQL, nhưng hỗ trợ nhiều loại cơ sở dữ liệu. Tuy nhiên, gặp phức tạp hơn và không phù hợp với tất cả các cơ sở dữ liệu trong .NET.
- LINQ to DataSets: Kết hợp giữa LINQ và ADO.NET để truy vấn thông tin trong các DataSet.
- LINQ to XML: Truy vấn thông tin trong file XML.
2. Câu lệnh truy vấn
Có hai cách để tạo ra câu lệnh truy vấn: cú pháp truy vấn (query syntax) và cú pháp phương thức (method syntax). Để viết câu truy vấn, chúng ta cần sử dụng thư viện System.Linq.
Dưới đây là ví dụ về việc tạo ra một danh sách các xe có năm sản xuất >= 1990 bằng cả hai cú pháp:
2.1. Cú pháp truy vấn
Sử dụng cú pháp giống như bạn truy vấn cơ sở dữ liệu. Mẫu cú pháp như sau:
var list = from <biến lưu thông tin từng phần tử> in <nguồn dữ liệu> [<phép toán truy vấn: where, join ... in, order by...> biểu thức lambda] select <biến lưu thông tin từng phần tử>
Ví dụ:
var cars = Car.Cars;
var list = from item in cars where item.YearOfManufacture >= 1990 select item;
2.2. Cú pháp phương thức
Cú pháp này sử dụng phương thức mở rộng của IEnumerable hoặc IEnumerable. Với ví dụ trên, chúng ta có thể viết lại code như sau:
var cars = Car.Cars;
var list = cars.Where(f => f.YearOfManufacture >= 1990);
3. Thực thi truy vấn để lấy kết quả
Có hai kiểu thực thi truy vấn:
- Trì hoãn thực thi (Deferred Execution): truy vấn chỉ được thực hiện khi chúng ta thực hiện foreach. Điều này giúp tăng hiệu năng vì truy vấn được thực thi chỉ một lần và dữ liệu trả về là mới nhất.
- Thực thi ngay lập tức (Immediate Execution): truy vấn được thực thi ngay lập tức và kết quả trả về. Để thực thi ngay lập tức, chúng ta có thể sử dụng các toán tử chuyển đổi như ToList, ToArray, ToDictionary hoặc các toán tử thành phần như First, FirstOrDefault, Last, LastOrDefault.
Ví dụ:
var cars = Car.Cars;
var list = cars.Where(f => f.YearOfManufacture >= 1990).ToList();
4. Lưu ý
Sau khi tìm hiểu đến đây, có thể bạn sẽ thắc mắc: Tại sao không sử dụng for hoặc foreach kết hợp if để truy vấn? Và LINQ có hiệu năng như thế nào? Việc sử dụng LINQ hay không sử dụng LINQ phụ thuộc vào quan điểm của từng người. LINQ có cú pháp dễ viết, ngắn gọn và dễ debug. Về hiệu năng, LINQ có thể chậm hơn so với việc sử dụng for hoặc foreach, tuy nhiên, với cấu hình máy tính hiện nay, sự chậm đó không ảnh hưởng đáng kể đến hiệu năng.
HEFC tại đây để cung cấp cho bạn kiến thức về LINQ và các công nghệ lập trình khác. Hãy truy cập hefc.edu.vn để tìm hiểu thêm!