Toán tử Select và SelectMany trong LINQ

Có hai toán tử projection có sẵn trong LINQ: Select và SelectMany. Chúng được sử dụng để định dạng kết quả trả về.

Toán tử projection là một trong những toán tử truy vấn chuẩn của LINQ.

Toán tử truy vấn chuẩn của LINQ | Comdy
Các toán tử truy vấn chuẩn trong LINQ là các phương thức mở rộng cho các kiểu IEnumerable<T> và IQueryable<T>.

Toán tử Select trong LINQ

Toán tử Select luôn trả về một danh sách IEnumerable chứa các phần tử dựa trên hàm biến đổi. Nó tương tự như mệnh đề SELECT của SQL tạo ra tập kết quả.

Bây giờ, chúng ta sẽ tìm hiểu toán tử truy vấn Select bằng cách sử dụng lớp Student sau.

public class Student
{ 
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public int Age { get; set; }
}

Mệnh đề Select trong Cú pháp truy vấn

Cú pháp truy vấn LINQ phải kết thúc bằng mệnh đề select hoặc groupby. Ví dụ sau đây cho thấy toán tử select trả về một danh sách kiểu chuỗi chứa StudentName.

// Student collection
IList<Student> studentList = new List<Student>() 
{ 
    new Student() { StudentID = 1, StudentName = "John" },
    new Student() { StudentID = 2, StudentName = "Moin" },
    new Student() { StudentID = 3, StudentName = "Bill" },
    new Student() { StudentID = 4, StudentName = "Ram" },
    new Student() { StudentID = 5, StudentName = "Ron"  } 
};

var selectResult = from s in studentList
                   select s.StudentName;
                  
foreach(var name in selectResult)
{            
    Console.WriteLine(name);
}

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

John
Moin
Bill
Ram
Ron

Toán tử select có thể được sử dụng để định dạng kết quả theo yêu cầu của chúng ta. Nó có thể được sử dụng để trả về một tập hợp các lớp tùy chỉnh hoặc kiểu ẩn danh chứa các thuộc tính theo nhu cầu của chúng ta.

Ví dụ sau đây của mệnh đề select trả về một tập hợp kiểu ẩn danh chứa thuộc tính Name và Age.

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 } 
};

// returns collection of anonymous objects with Name and Age property
var selectResult = from s in studentList
                   select new 
                   { 
                       Name = "Mr. " + s.StudentName, 
                       Age = s.Age 
                   }; 

// iterate selectResult
foreach (var item in selectResult)
{
    Console.WriteLine("Student Name: {0}, Age: {1}", item.Name, item.Age);
}

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

Student Name: Mr. John, Age: 13
Student Name: Mr. Moin, Age: 21
Student Name: Mr. Bill, Age: 18
Student Name: Mr. Ram, Age: 20
Student Name: Mr. Ron, Age: 15

Phương thức Select trong Cú pháp phương thức

Phương thức mở rộng Select là tùy chọn trong cú pháp phương thức. Tuy nhiên, bạn có thể sử dụng nó để định dạng dữ liệu.

Trong ví dụ sau,phương thức mở rộng Select trả về một tập hợp các đối tượng ẩn danh với thuộc tính Name và Age:

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 } 
};

// returns collection of anonymous objects with Name and Age property
var selectResult = studentList.Select(s => new 
{ 
    Name = s.StudentName,
    Age = s.Age
});

// iterate selectResult
foreach (var item in selectResult)
{
    Console.WriteLine("Student Name: {0}, Age: {1}", item.Name, item.Age);
}

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

Student Name: John, Age: 13
Student Name: Moin, Age: 21
Student Name: Bill, Age: 18
Student Name: Ram, Age: 20
Student Name: Ron, Age: 15

Trong ví dụ trên, tập kết quả trả về sẽ chứa các đối tượng ẩn danh với thuộc tính Name và Age như hiển thị bên dưới trong chế độ Debug.

Kết quả trả về của phương thức Select trong LINQ

Toán tử SelectMany trong LINQ

Toán tử SelectMany trong LINQ là gì?

SelectMany trong LINQ được sử dụng để chuyển đổi dữ liệu của từng phần tử trong danh sách (có dạng danh sách) thành một danh sách kết quả trả về.

Bây giờ, chúng ta sẽ tìm hiểu toán tử truy vấn SelectMany bằng cách sử dụng lớp Student sau.

public class Student
{ 
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public int Age { get; set; }
    public List<string> Programming { get; set; }
}

Mệnh đề SelectMany trong Cú pháp truy vấn

Ví dụ sau đây cho thấy toán tử select trả về một danh sách kiểu chuỗi chứa thông tin thuộc tính Programming (thuộc tính này kiểu danh sách chuổi).

IList<Student> studentList = new List<Student>()
{
    new Student(){ID = 1, Name = "James", Programming = new List<string>() { "C#", ".NET Core" }},
    new Student(){ID = 2, Name = "Sam", Programming = new List<string>() { "WCF", "SQL Server" }},
    new Student(){ID = 3, Name = "Patrik", Programming = new List<string>() { "MVC" }},
    new Student(){ID = 4, Name = "Sara", Programming = new List<string>() { "ADO.NET", "LINQ" }}
};

// returns collection of anonymous objects with Name and Age property
var selectResult = from s in studentList
                   select s.Programming; 

// iterate selectResult
foreach (var item in selectResult)
{
    Console.WriteLine(item);
}

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

C#
.NET Core
WCF
SQL Server
MVC
ADO.NET
LINQ

Phương thức SelectMany trong Cú pháp phương thức

Phương thức mở rộng SelectMany là tùy chọn trong cú pháp phương thức. Tuy nhiên, bạn có thể sử dụng nó để định dạng dữ liệu.

Trong ví dụ sau,phương thức mở rộng SelectMany trả về danh sách ngôn ngữ lập trình của tất cả sinh viên trong danh sách. Danh sách ngôn ngữ lập trình được trả về từ thuộc tính Programming (kiểu danh sách chuỗi):

IList<Student> studentList = new List<Student>()
{
    new Student(){ID = 1, Name = "James", Programming = new List<string>() { "C#", ".NET Core" }},
    new Student(){ID = 2, Name = "Sam", Programming = new List<string>() { "WCF", "SQL Server" }},
    new Student(){ID = 3, Name = "Patrik", Programming = new List<string>() { "MVC" }},
    new Student(){ID = 4, Name = "Sara", Programming = new List<string>() { "ADO.NET", "LINQ" }}
};

// returns collection of anonymous objects with Name and Age property
var selectResult = studentList.SelectMany(s => s.Programming); 

// iterate selectResult
foreach (var item in selectResult)
{
    Console.WriteLine(item);
}

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

C#
.NET Core
WCF
SQL Server
MVC
ADO.NET
LINQ

Truy cập MSDN để biết thêm thông tin về các toán tử projection trong LINQ.



Bài viết liên quan:

Bạn sẽ tìm hiểu một số truy vấn LINQ phức tạp trong hướng dẫn này.

Từ khóa let, into trong LINQ có tác dụng gì? Hướng dẫn khai báo và sử dụng từ khóa let, into trong LINQ.

Trì hoãn thực thi truy vấn LINQ là gì? Thực thi ngay lập tức truy vấn LINQ là gì? Làm sao để thực thi truy vấn LINQ.