C# Series 1- Giới thiệu về Linq và cách querry với Linq API

Linq Series 1- Giới thiệu về Linq và cách querry với Linq API

Chia sẻ kiến thức 18/03/2023

Giới thiệu về Linq

LINQ là viết tắt của Language Integrated Query, là một cơ chế truy vấn được tích hợp trong ngôn ngữ lập trình C# và VB.NET của Microsoft. LINQ cung cấp một cách thức tập trung và linh hoạt để truy vấn dữ liệu từ nhiều nguồn khác nhau, bao gồm các tập tin, cơ sở dữ liệu, tài liệu XML và bộ nhớ.

LINQ cho phép lập trình viên sử dụng một chuỗi truy vấn đơn giản để truy vấn và sắp xếp dữ liệu một cách linh hoạt, hiệu quả và dễ dàng hơn. Bằng cách sử dụng LINQ, các lập trình viên không cần phải biết rõ các ngôn ngữ truy vấn cụ thể như SQL, mà chỉ cần sử dụng các phương thức và thuộc tính LINQ để truy vấn dữ liệu.

LINQ cung cấp các phương thức truy vấn thông dụng như Select, Where, OrderBy, Join, GroupBy và Count, cho phép lập trình viên thực hiện các truy vấn phức tạp một cách dễ dàng. Bên cạnh đó, LINQ cũng hỗ trợ các kiểu dữ liệu tự định nghĩa và các toán tử mở rộng, cho phép lập trình viên tạo ra các truy vấn truy vấn tùy chỉnh của riêng mình.

Với các tính năng và ưu điểm vượt trội của nó, LINQ đã trở thành một công cụ quan trọng và phổ biến trong việc phát triển ứng dụng .NET. 

LINQ là gì?

Truy vấn LINQ trả về kết quả dưới dạng đối tượng. Nó cho phép bạn sử dụng cách tiếp cận hướng đối tượng trên tập kết quả và không phải lo lắng về việc chuyển đổi các định dạng khác nhau của kết quả thành các đối tượng.

 LINQ là gì?

 

Tại sao nên sử dụng Linq?

  • Ngôn ngữ quen thuộc: Nhà phát triển không phải học ngôn ngữ truy vấn mới cho từng loại nguồn dữ liệu hoặc định dạng dữ liệu.
  • Ít mã code hơn: Nó làm giảm số lượng mã được viết so với cách tiếp cận truyền thống hơn.
  • Mã code có thể đọc được: LINQ làm cho mã dễ đọc hơn để các nhà phát triển khác có thể dễ dàng hiểu và bảo trì mã.
  • Cách chuẩn hóa để truy vấn nhiều nguồn dữ liệu: Có thể sử dụng cùng một cú pháp LINQ để truy vấn nhiều nguồn dữ liệu.
  • An toàn thời gian biên dịch của các truy vấn: Nó cung cấp kiểm tra kiểu của các đối tượng tại thời điểm biên dịch.
  • Hỗ trợ IntelliSense: LINQ cung cấp IntelliSense cho các bộ sưu tập chung.
  • Định hình dữ liệu: Bạn có thể truy xuất dữ liệu theo các hình dạng khác nhau.

Linq API

Chúng ta có thể viết các truy vấn LINQ cho các lớp triển khai giao diện IEnumerable<T> hoặc IQueryable<T>. Namspace System.Linq bao gồm các class và interface sau đây cần cho các truy vấn LINQ.

Các truy vấn LINQ sử dụng các phương thức mở rộng cho các lớp triển khai interface IEnumerable hoặc IQueryable. Hai lớp static Enumerable và Queryable có chứa các phương thức mở rộng để viết các truy vấn LINQ.

Lưu ý: using System.Linq; đã được thêm vào khai báo lớp theo mặc định khi bạn thêm một lớp mới trong Visual Studio.

1. Enumerable

Lớp Enumerable bao gồm các phương thức mở rộng cho các lớp triển khai interface IEnumerable<T>, ví dụ như tất cả các kiểu collection generic được tích hợp sẵn trong C# đều triển khai interface IEnumerable<T> và vì vậy chúng ta có thể viết các truy vấn LINQ để lấy dữ liệu từ các collection tích hợp này.

Hình dưới đây cho thấy các phương thức mở rộng có trong lớp Enumerable có thể được sử dụng với các collection generic trong C# hoặc VB.Net.

Các phương thức mở rộng của lớp Enumerable

Hình dưới đây cho thấy tất cả các phương thức mở rộng có sẵn trong lớp Enumerable.

Tất cả các phương thức mở rộng có sẵn trong lớp Enumerable

2. Querryable

Lớp Queryable bao gồm các phương thức mở rộng cho các lớp triển khai interface IQueryable<T>. Interface IQueryable<T> được sử dụng để cung cấp khả năng truy vấn đối với một nguồn dữ liệu cụ thể mà các kiểu dữ liệu đã được biết đến. Ví dụ, các API của Entity Framework triển khai interface IQueryable<T> để hỗ trợ các truy vấn LINQ với cơ sở dữ liệu bên dưới như MS SQL Server.

Ngoài ra, còn có các API có sẵn để truy cập dữ liệu của bên thứ ba; ví dụ: LINQ to Amazon cung cấp khả năng sử dụng LINQ với các web service của Amazon để tìm kiếm sách và các mặt hàng khác. Điều này có thể đạt được bằng cách triển khai interface IQueryable cho Amazon.

Hình dưới đây cho thấy các phương thức mở rộng có sẵn trong lớp Queryable có thể được sử dụng với các nhà cung cấp dữ liệu gốc hoặc bên thứ ba khác nhau.

Các phương thức mở rộng của lớp Queryable

Hình dưới đây cho thấy tất cả các phương thức mở rộng có sẵn trong lớp Queryable.

Tất cả các phương thức mở rộng có sẵn trong lớp Queryable

3. Những điểm cần nhớ

  1. Sử dụng namespace System.Linq để sử dụng LINQ.
  2. LINQ API bao gồm hai lớp tĩnh chính Enumerable và Queryable.
  3. Lớp Enumerable tĩnh bao gồm các phương thức mở rộng cho các lớp triển khai interface IEnumerable<T>.
  4. Kiểu IEnumerable<T> là collection trong bộ nhớ như List<T>Dictionary<TKey, TValue>SortedList<TKey, TValue>Queue<T>Stack<T>Hashset<T>.
  5. Lớp Queryable tĩnh bao gồm các phương thức mở rộng cho các lớp triển khai interface IQueryable<T>.

Linq Syntax

Có 2 cách cơ bản để viết Linq querry với IEnumerable collection hoặc Iqueryable data sources.

  1. Query Syntax hay Query Expression Syntax (Cú pháp truy vấn Linq)
  2. Method Syntax hay Method Extension Syntax or Flue (Cú pháp phương thức Linq)

1. Cú pháp truy vấn Linq

Cú pháp truy vấn tương tự như truy vấn SQL (Ngôn ngữ truy vấn có cấu trúc) cho cơ sở dữ liệu. Nó có cú pháp trong mã C# hoặc VB.NET như sau:

from <range variable> in <IEnumerable<T> or IQueryable<T> Collection>


<Standard Query Operators> <lambda expression>


<select or groupBy operator> <result formation>

Cú pháp truy vấn LINQ bắt đầu bằng từ khóa from và kết thúc bằng từ khóa select. Điều này ngược với cú pháp truy vấn SQL bắt đầu bằng từ khóa select.

Lý do bắt đầu bằng từ khóa from là IntelliSense sẽ biết trước được kiểu dữ liệu để hỗ trợ bạn gõ biểu thức truy vấn nhanh chóng.

Ví dụ dưới đây minh họa một biểu thức truy vấn LINQ trả về các chuỗi có chứa từ “Tutorials”:

// string collection
IList<string> stringList = new List<string>() 
{ 
    "C# Tutorials",
    "VB.NET Tutorials",
    "Learn C++",
    "MVC Tutorials" ,
    "Java" 
};
// LINQ Query Syntax
var result = from s in stringList
             where s.Contains("Tutorials") 
             select s;
foreach(var item in result)
{
    Console.WriteLine(item);
}

Đây là kết quả khi biên dịch và thực thi chương trình trên:

C# Tutorials

VB.NET Tutorials

MVC Tutorials

Hình dưới đây cho thấy cấu trúc của cú pháp truy vấn LINQ.

Cú pháp biểu thức truy vấn LINQ

Cú pháp truy vấn bắt đầu bằng mệnh đề from theo sau là biến range. Từ khóa from có cấu trúc from s in strList có nghĩa là từ mỗi phần tử trong danh sách. Nó tương tự như một vòng lặp foreach:

foreach(var s in strList)
{
    // some code
}

Sau mệnh đề from, bạn có thể sử dụng các toán tử truy vấn tiêu chuẩn khác nhau để lọc, gom nhóm, nối các phần tử của danh sách. Có khoảng 50 toán tử truy vấn tiêu chuẩn có sẵn trong LINQ.

Trong ví dụ trên, chúng ta đã sử dụng toán tử where (còn được gọi là mệnh đề where) theo sau là một điều kiện. Điều kiện này thường được thể hiện bằng cách sử dụng biểu thức lambda.

Cú pháp truy vấn LINQ luôn kết thúc bằng mệnh đề select hoặc group by. Mệnh đề select được sử dụng để định hình dữ liệu. Bạn có thể chọn toàn bộ đối tượng hoặc chỉ một số thuộc tính của nó để trả về. Trong ví dụ đơn giản ở trên, do chỉ là danh sách chuỗi nền chúng tôi đã chọn những chuỗi thỏa điều kiện để trả về kết quả.

Trong ví dụ dưới đây, chúng tôi sử dụng cú pháp truy vấn LINQ để tìm ra các sinh viên có độ tuổi từ 13 đến 19 từ danh sách sinh viên.

// Student collection
IList<Student> studentList = new List<Student>() 
{ 
    new Student() { StudentID = 1, StudentName = "John", Age = 13},
    new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 },
    new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 },
    new Student() { StudentID = 4, StudentName = "Ram" , Age = 20},
    new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
};
// LINQ Query Syntax to find out teenager students
var result = (from s in studentList
              where s.Age > 12 && s.Age < 20
              select s).ToList();
foreach(var item in result)
{
    Console.WriteLine(item.StudentName);
}

Đây là kết quả khi biên dịch và thực thi chương trình trên:

John
Bill
Ron

2. Những điểm cần nhớ của cú pháp truy vấn LINQ

  1. Cú pháp truy vấn giống như cú pháp SQL (Ngôn ngữ truy vấn cấu trúc).
  2. Cú pháp truy vấn bắt đầu bằng mệnh đề from và có thể kết thúc bằng mệnh đề select hoặc group by.
  3. Sử dụng các thành phần khác như lọc, nối, nhóm, sắp xếp toán tử để xây dựng kết quả mong muốn.
  4. Biến được định kiểu ngầm định – var có thể được sử dụng để lưu trữ kết quả của truy vấn LINQ.

3. Cú pháp phương thức LINQ

Cú pháp phương thức LINQ sử dụng các phương thức mở rộng có trong hai lớp tĩnh là Enumerable hoặc Queryable, tương tự như cách bạn sẽ gọi các phương thức mở rộng của một lớp bất kỳ.

Lưu ý: Trình biên dịch sẽ chuyển đổi cú pháp truy vấn LINQ thành cú pháp phương thức LINQ tại thời điểm biên dịch.

Ví dụ dưới đây minh họa một truy vấn sử dụng cú pháp phương thức LINQ trả về những chuỗi có chứa một từ “Tutorials”.

// string collection
IList<string> stringList = new List<string>() 
{ 
    "C# Tutorials",
    "VB.NET Tutorials",
    "Learn C++",
    "MVC Tutorials" ,
    "Java" 
};
// LINQ Query Syntax
var result = stringList.Where(s => s.Contains("Tutorials")).ToList();
foreach(var item in result)
{
    Console.WriteLine(item);
}

Đây là kết quả khi biên dịch và thực thi chương trình trên:

C# Tutorials
VB.NET Tutorials
MVC Tutorials

Hình dưới đây minh họa cấu trúc của cú pháp phương thức LINQ.

Cú pháp phương thức truy vấn LINQ

Như bạn có thể thấy trong hình trên, cú pháp phương thức LINQ bao gồm các phương thức mở rộng và biểu thức lambda. Phương thức mở rộng Where được định nghĩa trong lớp Enumerable.

Nếu bạn kiểm tra chữ ký của phương thức mở rộng Where, bạn sẽ thấy phương thức này chấp nhận một predicate delegate là Func<Student, bool>.

Điều này có nghĩa là bạn có thể truyền bất kỳ phương thức nào chấp nhận đối tượng Student làm tham số đầu vào và trả về giá trị Boolean như trong hình dưới đây.

Biểu thức lambda hoạt động như một delegate được truyền vào phương thức Where.

Phương thức mở rộng Where trong LINQ

Ví dụ sau đây minh họa cách sử dụng cú pháp phương thức LINQ với danh sách IEnumerable<T>.

// Student collection
IList<Student> studentList = new List<Student>() 
{ 
    new Student() { StudentID = 1, StudentName = "John", Age = 13},
    new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 },
    new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 },
    new Student() { StudentID = 4, StudentName = "Ram" , Age = 20},
    new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
};
// LINQ Method Syntax to find out teenager students
var result = studentList.Where(s => s.Age > 12 && s.Age < 20)
                        .ToList();
foreach(var item in result)
{
    Console.WriteLine(item.StudentName);
}

Đây là kết quả khi biên dịch và thực thi chương trình trên:

John
Bill
Ron

4. Những điểm cần nhớ của cú pháp phương thức LINQ

  1. Cú pháp phương thức LINQ giống như gọi phương thức mở rộng.
  2. Cú pháp phương thức LINQ còn gọi là cú pháp thông thạo (fluent syntax) vì nó cho phép thực hiện hàng loạt các phương thức mở rộng.
  3. Biến được định kiểu ngầm định – var có thể được sử dụng để lưu trữ kết quả của truy vấn LINQ.

Tài liệu tham khảo

  1. https://comdy.vn/linq/linq-toan-tap/
  2. https://dotnettutorials.net/lesson/introduction-to-linq/
  3. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/
  4. https://www.tutorialsteacher.com/linq/linq-api

Học viên Phạm Tuấn Vũ

ĐĂNG KÝ TƯ VẤN HỌC LẬP TRÌNH TẠI FUNiX

Bình luận (
0
)

Bài liên quan

  • Tầng 0, tòa nhà FPT, 17 Duy Tân, Q. Cầu Giấy, Hà Nội
  • info@funix.edu.vn
  • 0782313602 (Zalo, Viber)        
Chat Button
Chat với FUNiX GPT ×

yêu cầu gọi lại

error: Content is protected !!