C# Series 1- Tìm hiểu về Linq và các phương thức thường sử dụng trong Linq
- 6 cách để kiểm tra phiên bản .NET Framework nào được cài đặt trên PC
- Cách khắc phục mã lỗi 0x80071AB1 khi cài đặt .NET
- Những câu hỏi thường gặp về khóa học Lập trình Automotive tại FUNiX
- Giải đáp điều kiện if-else trong ngôn ngữ C
- Sự khác biệt giữa ngôn ngữ lập trình C với C99, ANSI C và GNU C
Table of Contents
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.
Một số phương thức thường sử dụng trong Linq
1. Phương thức Select
Phương thức Select trong LINQ được sử dụng để trích xuất và chuyển đổi dữ liệu từ một danh sách hoặc tập hợp sang một danh sách hoặc tập hợp mới bằng cách áp dụng một hàm chuyển đổi trên từng phần tử. Cú pháp của phương thức Select như sau:
public static IEnumerable<TResult> Select<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TResult> selector
)
Trong đó:
– source
: là danh sách hoặc tập hợp cần trích xuất dữ liệu.
– selector
: là hàm chuyển đổi được áp dụng lên từng phần tử trong danh sách hoặc tập hợp source
, trả về một giá trị mới.
Ví dụ:
int[] numbers = { 1, 2, 3, 4, 5 };
var squaredNumbers = numbers.Select(x => x * x);
Trong ví dụ này, phương thức Select được sử dụng để trích xuất và chuyển đổi dữ liệu từ danh sách numbers
sang một danh sách mới squaredNumbers
với mỗi phần tử là bình phương của các phần tử trong danh sách numbers
.
2. Phương thức SelectMany
Phương thức SelectMany trong LINQ được sử dụng để thực hiện việc kết hợp các phần tử từ nhiều danh sách (collections) thành một danh sách (collection) duy nhất. Các phần tử trong danh sách mới được tạo ra bằng cách ghép cặp các phần tử từ các danh sách ban đầu. Phương thức SelectMany có cú pháp như sau:
public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource, TResult>(
this System.Collections.Generic.IEnumerable<TSource> source,
Func<TSource, System.Collections.Generic.IEnumerable<TResult>> selector);
Trong đó:
– source
là danh sách ban đầu được truyền vào để kết hợp.
– selector
là một hàm delegate (một kiểu dữ liệu đặc biệt trong C#) được sử dụng để lấy danh sách các phần tử từ các phần tử trong source
.
Với mỗi phần tử trong source
, selector
trả về một danh sách các phần tử.
– Kết quả trả về là một danh sách các phần tử mới được hình thành từ các phần tử trong danh sách ban đầu và danh sách phần tử được trả về bởi selector
.
Ví dụ minh họa: Giả sử chúng ta có hai danh sách list1
và list2
như sau:
List<string> list1 = new List<string>() { "A", "B", "C" };
List<string> list2 = new List<string>() { "X", "Y", "Z" };
Chúng ta sử dụng phương thức SelectMany để kết hợp các phần tử của hai danh sách này như sau:
var result = list1.SelectMany(x => list2, (a, b) => a + b);
Kết quả là một danh sách mới được hình thành từ việc kết hợp các phần tử của hai danh sách ban đầu:
["AX", "AY", "AZ", "BX", "BY", "BZ", "CX", "CY", "CZ"]
Trong ví dụ này, x => list2
là hàm delegate được sử dụng để lấy tất cả các phần tử trong list2
cho mỗi phần tử trong list1
. Khi kết hợp, chúng ta sử dụng hàm delegate (a, b) => a + b
để ghép các phần tử a
từ list1
với các phần tử b
từ list2
.
3. Phương thức Where
Phương thức Where trong LINQ được sử dụng để lọc dữ liệu trong một đối tượng IEnumerable<T> (hoặc IQueryable<T>) dựa trên một điều kiện được cung cấp trong một biểu thức lambda. Cú pháp của phương thức Where như sau:
IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
Ở đó:
– source: Đối tượng IEnumerable cần lọc.
– predicate: Một biểu thức lambda chứa điều kiện để lọc dữ liệu.
Ví dụ:
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0);
foreach (int number in evenNumbers)
{
Console.WriteLine(number);
}
// Kết quả:
// 2
// 4
Ở ví dụ trên, ta sử dụng phương thức Where để lọc các số chẵn từ danh sách số nguyên. Biểu thức lambda n => n % 2 == 0
được sử dụng để kiểm tra xem một số có phải là số chẵn hay không. Kết quả trả về là một đối tượng IEnumerable<T> chứa danh sách các số chẵn trong danh sách ban đầu.
4. Phương thức GroupBy
Phương thức GroupBy trong Linq là một phương thức mở rộng (extension method) của đối tượng IQueryable. Phương thức này cho phép chúng ta nhóm các phần tử trong một bộ dữ liệu theo một thuộc tính hoặc nhiều thuộc tính cụ thể. Cú pháp của phương thức GroupBy như sau:
public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector
)
Trong đó:
– source
là bộ dữ liệu cần nhóm.
– keySelector
là một hàm thuộc kiểu Func<TSource, TKey>
có tác dụng trích xuất thuộc tính để nhóm dữ liệu theo.
Kết quả trả về khi sử dụng phương thức GroupBy là một danh sách các nhóm (group) – mỗi nhóm là một tập hợp các phần tử trong bộ dữ liệu cùng các giá trị của thuộc tính được nhóm theo.
Thông thường, chúng ta sử dụng phương thức GroupBy để thống kê và phân tích dữ liệu, từ đó đưa ra các kết luận hoặc quyết định trong lập trình.
Dưới đây là ví dụ về phương thức GroupBy trong linq sử dụng method syntax:
// Khởi tạo danh sách các sản phẩm
List<Product> productList = new List<Product>()
{
new Product { Name = "Product A", Category = "Category 1", Price = 10 },
new Product { Name = "Product B", Category = "Category 2", Price = 15 },
new Product { Name = "Product C", Category = "Category 1", Price = 20 },
new Product { Name = "Product D", Category = "Category 2", Price = 25 },
new Product { Name = "Product E", Category = "Category 3", Price = 30 }
};
// Sử dụng phương thức GroupBy để nhóm các sản phẩm theo danh mục
var groupedProducts = productList.GroupBy(p => p.Category);
// In kết quả
foreach (var group in groupedProducts)
{
Console.WriteLine("Category: " + group.Key);
foreach (var product in group)
{
Console.WriteLine("- " + product.Name + " (" + product.Price + ")");
}
}
Kết quả in ra màn hình:
Category: Category 1
- Product A (10)
- Product C (20)
Category: Category 2
- Product B (15)
- Product D (25)
Category: Category 3
- Product E (30)
5. Phương thức Join
Phương thức Join() trong LINQ là một phương thức cho phép bạn kết hợp (join) hai hoặc nhiều bộ dữ liệu khác nhau, thông qua các giá trị khóa (key values) chung của chúng. Kết quả của phương thức Join() là một tập hợp các đối tượng mới, mà mỗi đối tượng mới đại diện cho kết quả của việc ghép các bộ dữ liệu. Cú pháp của phương thức Join() trong LINQ như sau:
IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>( this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector );
Trong đó:
– outer
: Bộ sưu tập các đối tượng bên ngoài (outer collection).
– inner
: Bộ sưu tập các đối tượng bên trong (inner collection).
– outerKeySelector
: Một hàm delegate để chọn khóa (key) từ mỗi đối tượng trong outer collection.
– innerKeySelector
: Một hàm delegate để chọn khóa (key) từ mỗi đối tượng trong inner collection.
– resultSelector
: Một hàm delegate để tạo ra kết quả từ mỗi cặp đối tượng đã kết hợp.
Dưới đây là một ví dụ về cách sử dụng nó thông qua method syntax:
// Khởi tạo hai danh sách các số nguyên.
List<int> list1 = new List<int>() { 1, 2, 3, 4, 5 };
List<int> list2 = new List<int>() { 3, 4, 5, 6, 7 };
// Thực hiện phép join trên hai danh sách.
var joinedList = list1.Join(
list2, // Danh sách cần join.
num1 => num1, // Hàm chọn key trong danh sách 1.
num2 => num2, // Hàm chọn key trong danh sách 2.
(num1, num2) => num1); // Hàm kết quả (lấy key của danh sách 1).
// In kết quả
foreach (var num in joinedList)
{
Console.Write(num + " ");
}
// Kết quả là danh sách các số 3, 4 và 5, bởi vì chúng xuất hiện trong cả hai danh sách.
Trong ví dụ này, ta áp dụng phương thức Join trên list1
và list2
. Ta truyền cho phương thức Join hai đối số là hai danh sách cần kết hợp và hai hàm định nghĩa key để tìm sự khớp nhau giữa hai danh sách này. Cuối cùng, ta cung cấp một hàm để định nghĩa kết quả mong muốn. Trong trường hợp này, ta muốn lấy key từ danh sách 1. Kết quả cuối cùng được lưu trữ trong joinedList
và được in ra màn hình sử dụng một vòng lặp for-each.
6. Phương thức GroupJoin
Phương thức GroupJoin trong Linq được sử dụng để kết hợp hai bộ dữ liệu trên cơ sở một khóa chính và khóa ngoại trên cả hai bộ dữ liệu. Cú pháp của phương thức GroupJoin trong Linq như sau:
public static IQueryable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>( this IQueryable<TOuter> outer, IQueryable<TInner> inner, Expression<Func<TOuter, TKey>> outerKeySelector, Expression<Func<TInner, TKey>> innerKeySelector, Expression<Func<TOuter, IEnumerable<TInner>, TResult>> resultSelector )
Ở đây: – TOuter là kiểu của bộ dữ liệu ngoài cùng. TInner là kiểu của bộ dữ liệu trong cùng.
– TKey
là kiểu dữ liệu của khóa chính ngoài cùng và khóa ngoại trong cùng.
– TResult
là kiểu của bộ dữ liệu kết quả trả về.
– outerKeySelector
là biểu thức để lấy khóa chính từ bộ dữ liệu ngoài cùng.
– innerKeySelector
là biểu thức để lấy khóa ngoại từ bộ dữ liệu trong cùng.
– resultSelector
là biểu thức để lấy dữ liệu kết quả từ kết quả được ghép cặp.
Ví dụ về sủ dụng phương thức GroupJoin trong linq
departments
và employees
. Ta sử dụng phương thức GroupJoin để kết hợp hai danh sách này theo thuộc tính DepartmentId
. Kết quả trả về là một danh sách các đối tượng chứa thông tin về Department
và danh sách Employees
của nó. Ta sử dụng một vòng lặp foreach
để in ra kết quả trả về.7. Phương thức Count
Phương thức Count trong LINQ được sử dụng để đếm số lượng phần tử trong một tập hợp (collection) hoặc bộ sưu tập (sequence). Nó trả về số nguyên không âm – số lượng phần tử được đếm. Cú pháp sử dụng:
var count = collection.Count();
Ví dụ, nếu bạn muốn đếm số lượng người trong một danh sách liên lạc:
List<Contact> contacts = GetContacts();
int numberOfContacts = contacts.Count();
Nếu bạn muốn đếm số lượng sản phẩm có số lượng tồn kho lớn hơn 0 trong một danh sách sản phẩm:
List<Product> products = GetProducts();
int numberOfAvailableProducts = products.Count(p => p.Inventory > 0);
Ở đây, tham số truyền vào lambda expression (p => p.Inventory > 0) được sử dụng để chỉ định điều kiện đếm.
Tài liệu tham khảo
- https://comdy.vn/linq/linq-toan-tap/
- https://dotnettutorials.net/lesson/introduction-to-linq/
- https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/
Học viên Phạm Tuấn Vũ
Bình luận (0
)