Kết nối

[LINQ] Phần 6: Cú pháp truy vấn và cú pháp phương thức trong LINQ (C#)

14.338 lượt xem 
 Cập nhật lần cuối: 13/07/2018 lúc 14:12:56

Đa số các truy vấn LINQ trong loại bài này đều được viết bằng cách sử dụng các cú pháp truy vấn khai báo LINQ. Tuy nhiên, cú pháp truy vấn phải được dịch thành các cuộc gọi phương thức cho lúc thực thi ngôn ngữ chung (common language runtime – CLR) khi mã nguồn được biên dịch. Các cuộc gọi phương thức này sử dụng các toán tử truy vấn chuẩn, chẳng hạn như Where, Select, GroupBy, Join, Max, and Average. Chúng ta có thể dùng các cú pháp phương thức thay vì dùng cú pháp truy vấn.

Cú pháp truy vấncú pháp phương thức đều có ngữ nghĩa giống nhau, tuy nhiên nhiều người nhận thấy cú pháp truy vấn đơn giản hơn và dễ đọc hơn. Một số truy vấn được diễn giải thành các cuộc gọi phương thức. Ví dụ, bạn phải dùng một cuộc gọi phương thức để lấy số phần tử thỏa mãn 1 điều kiện nào đó. Chúng ta cũng có thể dùng một cuộc gọi phương thức để truy vấn các phần tử có giá trị tối đa trong tập dữ liệu nguồn.

Các phương thức mở rộng toán tử truy vấn chuẩn

Ví dụ sau cho thấy 1 diễn giải truy vấn đơn giản và một truy vấn tương tự được viết bằng 1 truy vấn dựa trên phương thức.

static void Main()
{
int[] numbers = { 15, 7, 8, 5, 6, 2};

//Cú pháp truy vấn --- dammio.com
IEnumerable<int> listEvenNumber1 = from num in numbers
                                   where num % 2 == 0
                                   orderby num
                                  select num;

//Cú pháp phương thức
IEnumerable<int> listEvenNumber2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);

// Kết quả của cú pháp truy vấn
foreach (int i in listEvenNumber1)
{
    Console.Write(i + " ");
}

Console.WriteLine(System.Environment.NewLine); // xuống dòng

// Kết quả của cú pháp phương thức
foreach (int i in listEvenNumber2)
{
        Console.Write(i + " ");
}

// Giữ cửa sổ consolo mở trong chế độ debug --- dammio.com
Console.WriteLine(System.Environment.NewLine);
Console.WriteLine("Nhấn bất kỳ phím nào để thoát!");
Console.ReadKey();
}

/*
Kết quả:
       8 6 2 
       8 6 2
*/

Trong ví dụ trên, chúng ta thấy kiểu biến truy vấn trong 2 dạng truy vấn (truy vấn cú pháp & truy vấn phương thức) có cùng 1 kiểu là IEnumerable<T>. Cú pháp truy vấn thì viết câu truy vấn na ná như truy vấn SQL cũng bao gồm from, where, select … Ngược lại, cú pháp phương thức thì gọi các phương thức tương tự với việc truyền các đối số.

Liên quan:  [LINQ] Phần 7: Các tính năng trong C# hỗ trợ LINQ

Diễn giải Lambda

Trong ví dụ trên, chúng ta thấy diễn giải điều kiện (num % 2 == 0) được đẩy ra thành 1 đối số nội dòng (hay trong dòng – inline) của phương thức Where: Where(num => num % 2 == 0). Diễn giải nội dòng này được gọi là 1 diễn giải Lambda (Lambda expression). Đây là cách tiện lợi để viết mã nguồn.

Where(num => num % 2 == 0)

Trong C#, ký hiệu => được gọi là toán tử lambda, được gọi là “đi đến”. Biến bên trái toán tử là biến đầu vào, trong ví dụ tên là num. Trình biên dịch để suy luận kiểu biến num này từ T của IEnumerable<T>. Phần giữa của lambda giống như diễn giải trong cú pháp truy vấn hay bất cứ các diễn giải C# nào khác bao gồm: các phương thức gọi và các logic phức tạp. Giá trị trả về là kết quả của diễn giải.

Khi bắt đầu học LINQ, chúng ta không cần phải dùng lambda trước mà từ từ để sau cũng đươc. Khi bạn đã rành LINQ, bạn sẽ thấy lambda là công cụ rất mạnh, linh hoạt, và ngắn gọn để viết các truy vấn LINQ.

Kết hợp cú pháp truy vấn và phương thức truy vấn
Trong các dự án thực tế, bạn có thể kết hợp cả 2 cách truy vấn này trên cùng 1 câu truy vấn miễn sao đảm bảo về mặt dữ liệu và các gọi phương thức không phát sinh ra lỗi nào.

Trong ví dụ sau, chúng ta có thể biến câu truy vấn có phương pháp “lai căng” như sau.

int[] numbers = { 15, 7, 8, 5, 6, 2 };

//Cú pháp truy vấn
IEnumerable<int> listEvenNumber1 = (from num in numbers
                       where num % 2 == 0 select num).OrderBy(x=>x);

Theo nhiều lập trình viên thì nên chỉ chọn 1 trong 2 kiểu cú pháp, đa số chọn cú pháp phương thức vì viết gọn hơn.

Kết luận: bài viết đã trình bày cho bạn 2 cách dùng cú pháp truy vấn LINQ: cú pháp truy vấn và cú pháp phương thức. Bạn có thể kết hợp 2 kiểu này lại để áp dụng câu truy vấn mới. Đồng thời bạn cũng tìm hiểu được cấu trúc, cách hoạt động cũng như lợi ích của diễn giải lambda.

Trích dẫn bài viết
  • APA:
    Dammio. (2016). [LINQ] Phần 6: Cú pháp truy vấn và cú pháp phương thức trong LINQ (C#). https://www.dammio.com/2016/12/31/linq-phan-6-cu-phap-truy-van-va-cu-phap-phuong-thuc-trong-linq-c.
  • BibTeX:
    @misc{dammio,
    author = {Dammio},
    title = {[LINQ] Phần 6: Cú pháp truy vấn và cú pháp phương thức trong LINQ (C#)},
    year = {2016},
    url = {https://www.dammio.com/2016/12/31/linq-phan-6-cu-phap-truy-van-va-cu-phap-phuong-thuc-trong-linq-c},
    urldate = {2024-03-14}
    }
Thẻ: , , , ,
Theo dõi
Thông báo của
guest
2 Góp ý
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất
Phản hồi nội tuyến
Xem tất cả bình luận
2
0
Rất thích suy nghĩ của bạn, hãy bình luận.x