Bài 13.1. Tổng quan về LINQ
Nội dung bài học
(***) Yêu cầu bắt buộc: bạn phải học C# cơ bản và SQL trước khi học các bài học của chương LINQ này.
Tổng quan về LINQ
- LINQ là viết tắt của Language-Integrated Query: tên một tập các công nghệ dựa trên nền tảng tích hợp khả năng truy vấn trực tiếp vào ngôn ngữ C#. Đây là tính năng tuyệt vời của C# giúp cho việc thực hiện truy vấn dữ liệu từ nhiều nguồn data trở nên đơn giản.
- Truy vấn là một biểu thức truy cập dữ liệu từ một nguồn dữ liệu nào đó. Các truy vấn thường được biểu diễn trong một ngôn ngữ truy vấn cụ thể.
- Thông thường ta phải học nhiều ngôn ngữ truy vấn khác nhau để làm việc tùy theo từng nguồn dữ liệu: CSDL SQL, tài liệu XML, các dịch vụ web…
- Với LINQ, một truy vấn là một cấu trúc của ngôn ngữ giống như các lớp, phương thức và sự kiện.
- Sử dụng biểu thức truy vấn tạo nên từ các cú pháp truy vấn để sắp xếp, lọc, nhóm dữ liệu.
- Ta có thể sử dụng cùng mẫu cấu trúc truy vấn cho việc truy xuất và chuyển đổi dữ liệu trong CSDL SQL, ADO.NET dataset, tài liệu XML, các collections của .NET.
- Sau đây là hình ảnh minh họa của việc sử dụng LINQ:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Chapter11
{
class Lesson112
{
static void Main()
{
Console.OutputEncoding = Encoding.UTF8;
// tập dữ liệu mẫu danh sách sinh viên
var students = new List<Student>()
{
new Student("B25DCCN100", "Trần Trung Đức", "Hà Nội"),
new Student("B25DCCN105", "Lê Khả Ngân", "Nam Định"),
new Student("B25DCCN103", "Hoàng Thanh Mai", "Đà Nẵng"),
new Student("B25DCCN109", "Nguyễn Thúy Quyên", "Hà Nội"),
new Student("B25DCCN106", "Nông Tiến Mạnh", "Thái Nguyên"),
new Student("B25DCCN101", "Hồ Hoài Anh", "Hà Nội"),
new Student("B25DCCN104", "Trương Thanh Thức", "Hồ Chí Minh")
};
// câu lệnh truy vấn với LINQ: giống với SQL nhưng viết trực tiếp trong C#
var studentNameQuery = from student in students
where student.Address == "Hà Nội"
orderby student.Id
select student;
// thực thi và hiện kết quả
Console.WriteLine("==> Danh sách sinh viên:");
foreach (var item in studentNameQuery)
{
Console.WriteLine(item);
}
}
}
struct Student
{
public string Id { get; set; }
public string FullName { get; set; }
public string Address { get; set; }
public Student(string id, string fullName, string address)
{
Id = id;
FullName = fullName;
Address = address;
}
public override string ToString() => $"Student[{Id}, {FullName}, {Address}]";
}
}
==> Danh sách sinh viên:
Student[B25DCCN100, Trần Trung Đức, Hà Nội]
Student[B25DCCN101, Hồ Hoài Anh, Hà Nội]
Student[B25DCCN109, Nguyễn Thúy Quyên, Hà Nội]
Các đặc trưng của LINQ
- Biểu thức truy vấn có thể sử dụng để truy vấn và chuyển đổi dữ liệu từ bất kì nguồn dữ liệu nào hỗ trợ LINQ.
- Biểu thức truy vấn dễ học và sử dụng vì nó giống với cấu trúc của ngôn ngữ C#.
- Các biến trong biểu thức truy vấn có kiểu cụ thể mặc dù trong nhiều trường hợp bạn không cần cung cấp kiểu tường minh vì trình biên dịch có thể tự suy luận kiểu của chúng.
- Một câu lệnh truy vấn chỉ được thực thi khi ta duyệt các biến truy vấn, ví dụ khi ta sử dụng câu lệnh foreach.
- Tại thời điểm biên dịch chương trình, biểu thức truy vấn được chuyển thành các lời gọi phương thức toán tử truy vấn chuẩn theo các quy tắc được đặt ra trong đặc tả của C#.
- Giống như 1 quy tắc khi viết truy vấn LINQ, khuyến nghị sử dụng cú pháp truy vấn bất cứ khi nào có thể và sử dụng cú pháp phương thức khi cần thiết.
- Một số toán tử truy vấn như Max, Count không có biểu thức truy vấn tương ứng và phải thể hiện dưới dạng lời gọi phương thức. Cú pháp phương thức có thể kết hợp với cú pháp truy vấn theo nhiều cách khác nhau.
- Biểu thức truy vấn có thể biên dịch thành biểu thức cây hoặc delegate tùy vào kiểu mà truy vấn đang áp dụng.
Khi nào sử dụng LINQ?
Nhìn chung, LINQ có thể được sử dụng mềm dẻo ở bất cứ kịch bản nào trong đó bạn cần quy vấn hoặc quản lý dữ liệu theo cách ngắn gọn và trực tiếp trong C#. Sau đây là một số ngữ cảnh chính trong đó ta sử dụng tới LINQ:
- Làm việc với các Collections:
- LINQ đặc biệt hữu dụng khi làm việc với các tập hợp lưu trong bộ nhớ như arrays, list, dictionary… Nó cho phép ta thực hiện các truy vấn phức tạp, lọc, sắp xếp và chuyển đổi kiểu dữ liệu trên các tập hợp đó.
- Ví dụ: nếu bạn cần lọc một danh sách các mặt hàng dựa trên khoảng giá, LINQ có thể giúp bạn thực hiện nhanh chóng qua đoạn mã ngắn gọn và dễ đọc hiểu.
- Truy vấn cơ sở dữ liệu:
- Khi làm việc với database như SQL Server, LINQ cung cấp cho bạn khả năng viết các truy vấn trực tiếp trong ngôn ngữ C#.
- Ta có thể sử dụng LINQ để truy cập dữ liệu từ các bảng, ghép nối các bảng với nhau, áp dụng các bộ lọc, chiếu kết quả lên các đối tượng tùy chỉnh.
- Xử lý XML:
- Ta có thể thực hiện truy vấn và quản lý dữ liệu trong XML với cú pháp của LINQ.
- Nếu bạn đang chuyển đổi file XML hoặc làm việc với các API trên nền tảng XML, LINQ sẽ giúp bạn đơn giản hóa các dòng code.
- Chuyển đổi dữ liệu:
- LINQ cho phép ta chuyển đổi dữ liệu một cách dễ dàng. Ví dụ ta có thể đưa một tập hợp các đối tượng sang một dạng thức mới qua các thao tác như select các thuộc tính cụ thể, tính toán giá trị trung bình cộng, tổng.
- Điều này hết sức quan trọng trong những trường hợp ta cần trích xuất một thông tin cụ thể nào đó từ một tập dữ liệu lớn.
- Trì hoãn thực thi:
- LINQ sử dụng kĩ thuật trì hoãn việc thực thi truy vấn, tức là các truy vấn sẽ không thực thi ngay lập tức mà thay vào đó, chúng chỉ được thực thi khi kết quả của chúng là cần thiết để thực hiện tiếp một thao tác nào đó.
- Kĩ thuật lười biếng(lazy) này có thể cải thiện hiệu năng bằng cách tránh những tính toán không cần thiết.