Toán tử chuyển đổi trong LINQ

Các toán tử chuyển đổi trong LINQ rất hữu ích trong việc chuyển đổi kiểu dữ liệu của phần tử trong một danh sách.

Có ba loại toán tử chuyển đổi:

  • Toán tử As (AsEnumerable và AsQueryable).
  • Toán tử To (ToArray, ToDipedia, ToList và ToLookup).
  • Toán tử Casting (Cast và OfType).

Bảng sau liệt kê tất cả các toán tử chuyển đổi.

Phương thức Mô tả
AsEnumerable Trả về tập hợp đầu vào dưới dạng IEnumerable<T>
AsQueryable Chuyển đổi từ IEnumerable<T> sang IQueryable, để mô phỏng nhà cung cấp truy vấn từ xa
Cast Chuyển đổi tập hợp non-generic sang tập hợp generic (IEnumerable to IEnumerable<T>)
OfType Lọc một tập hợp dựa trên một kiểu dữ liệu được chỉ định
ToArray Chuyển đổi một tập hợp thành một mảng
ToDictionary Đưa các phần tử vào Dictionary dựa trên chức năng chọn khóa.
ToList Chuyển đổi tập hợp thành Danh sách
ToLookup Nhóm các thành phần vào Lookup<TKey,TElement>

Toán tử chuyển đổi 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>.

Phương thức AsEnumerable trong LINQ

Phương thức AsEnumerable ép kiểu một đối tượng nguồn thành kiểu IEnumerable<T>.

class Program
{
    static void ReportTypeProperties<T>(T obj)
    {
        Console.WriteLine("Compile-time type: {0}", typeof(T).Name);
        Console.WriteLine("Actual type: {0}", obj.GetType().Name);
    }

    static void Main(string[] args)
    {
        Student[] studentArray = 
        { 
            new Student() { StudentID = 1, StudentName = "John", Age = 18 },
            new Student() { StudentID = 2, StudentName = "Steve", Age = 21 },
            new Student() { StudentID = 3, StudentName = "Bill", Age = 25 },
            new Student() { StudentID = 4, StudentName = "Ram", Age = 20 },
            new Student() { StudentID = 5, StudentName = "Ron", Age = 31 }
        };   
            
        ReportTypeProperties(studentArray);
        ReportTypeProperties(studentArray.AsEnumerable());
    }
}

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

Compile-time type: Student[]
Actual type: Student[]
Compile-time type: IEnumerable`1
Actual type: Student[]
Lưu ý: Phương thức AsEnumerable không hỗ trợ  cú pháp truy vấn LINQ.

Phương thức AsQueryable trong LINQ

Phương thức AsQueryable chuyển đổi một đối tượng nguồn thành kiểu IQueryable<T>.

class Program
{
    static void ReportTypeProperties<T>(T obj)
    {
        Console.WriteLine("Compile-time type: {0}", typeof(T).Name);
        Console.WriteLine("Actual type: {0}", obj.GetType().Name);
    }

    static void Main(string[] args)
    {
        Student[] studentArray = 
        { 
            new Student() { StudentID = 1, StudentName = "John", Age = 18 },
            new Student() { StudentID = 2, StudentName = "Steve", Age = 21 },
            new Student() { StudentID = 3, StudentName = "Bill", Age = 25 },
            new Student() { StudentID = 4, StudentName = "Ram", Age = 20 },
            new Student() { StudentID = 5, StudentName = "Ron", Age = 31 }
        };   
            
        ReportTypeProperties(studentArray);
        ReportTypeProperties(studentArray.AsQueryable());   
    }
}

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

Compile-time type: Student[]
Actual type: Student[]
Compile-time type: IQueryable`1
Actual type: EnumerableQuery`1
Lưu ý: Phương thức AsQueryable không hỗ trợ  cú pháp truy vấn LINQ.

Phương thức Cast trong LINQ

Phương thức Cast thực hiện điều tương tự như phương thức AsEnumerable<T>. Nó ép kiểu một đối tượng nguồn thành kiểu IEnumerabl<T>.

class Program
{
    static void ReportTypeProperties<T>(T obj)
    {
        Console.WriteLine("Compile-time type: {0}", typeof(T).Name);
        Console.WriteLine("Actual type: {0}", obj.GetType().Name);
    }

    static void Main(string[] args)
    {
        Student[] studentArray = 
        { 
            new Student() { StudentID = 1, StudentName = "John", Age = 18 },
            new Student() { StudentID = 2, StudentName = "Steve", Age = 21 },
            new Student() { StudentID = 3, StudentName = "Bill", Age = 25 },
            new Student() { StudentID = 4, StudentName = "Ram", Age = 20 },
            new Student() { StudentID = 5, StudentName = "Ron", Age = 31 }
        };   
            
        ReportTypeProperties(studentArray);
        ReportTypeProperties(studentArray.Cast<Student>());   
    }
}

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

Compile-time type: Student[]
Actual type: Student[]
Compile-time type: IEnumerable`1
Actual type: Student[]

studentArray.Cast<Student>() giống như (IEnumerable<Student>)studentArray. Nhưng Cast<Student>() ngắn gọn và dễ đọc hơn.

Lưu ý: Phương thức Cast không hỗ trợ  cú pháp truy vấn LINQ.

Phương thức ToArray trong LINQ

Phương thức ToArray chuyển đổi một đối tượng nguồn thành kiểu mảng. ToArray là một toán tử To.

Toán tử To bắt buộc thực hiện các truy vấn. Nó buộc trình cung cấp truy vấn từ xa (remote query provider) thực hiện truy vấn và nhận kết quả từ nguồn dữ liệu - ví dụ: cơ sở dữ liệu SQL Server.

Ví dụ minh họa phương thức ToArray với tập hợp có kiểu dữ liệu nguyên thủy:


IList<string> strList = new List<string>() { "Two", "One", "Three", "Four", "Three" };

Console.WriteLine("strList type: {0}", strList.GetType().Name);
		
string[] strArray = strList.ToArray<string>();// converts List to Array

Console.WriteLine("strArray type: {0}", strArray.GetType().Name);

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

strList type: List`1
strArray type: String[]
Lưu ý: Phương thức ToArray không hỗ trợ  cú pháp truy vấn LINQ.

Phương thức ToList trong LINQ

Phương thức ToList chuyển đổi một đối tượng nguồn thành kiểu List. ToList là một toán tử To.

Toán tử To bắt buộc thực hiện các truy vấn. Nó buộc trình cung cấp truy vấn từ xa (remote query provider) thực hiện truy vấn và nhận kết quả từ nguồn dữ liệu - ví dụ: cơ sở dữ liệu SQL Server.

Ví dụ minh họa phương thức ToList với tập hợp có kiểu dữ liệu nguyên thủy:


IList<string> strList = new List<string>() { "Two", "One", "Three", "Four", "Three" };

Console.WriteLine("strList type: {0}", strList.GetType().Name);
		
IList<string> newList = strArray.ToList<string>(); // converts array into list

Console.WriteLine("newList type: {0}", newList.GetType().Name);

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

strList type: List`1
newList type: List`1
Lưu ý: Phương thức ToList không hỗ trợ  cú pháp truy vấn LINQ.

Phương thức ToDictionary trong LINQ

Phương thức ToDictionary chuyển đổi một đối tượng nguồn thành kiểu Dictionary. ToDictionary là một toán tử To.

Toán tử To bắt buộc thực hiện các truy vấn. Nó buộc trình cung cấp truy vấn từ xa (remote query provider) thực hiện truy vấn và nhận kết quả từ nguồn dữ liệu - ví dụ: cơ sở dữ liệu SQL Server.

Ví dụ minh họa phương thức ToDictionary với tập hợp có kiểu dữ liệu nguyên thủy:

IList<Student> studentList = new List<Student>() 
{ 
    new Student() { StudentID = 1, StudentName = "John", Age = 18 },
    new Student() { StudentID = 2, StudentName = "Steve", Age = 21 },
    new Student() { StudentID = 3, StudentName = "Bill", Age = 18 },
    new Student() { StudentID = 4, StudentName = "Ram", Age = 21 },
    new Student() { StudentID = 5, StudentName = "Ron", Age = 21 } 
};

//following converts list into dictionary where StudentId is a key
var studentDict = studentList.ToDictionary<Student, int>(s => s.StudentID); 

foreach(var item in studentDict)
{
    Console.WriteLine("Key: {0}, Value: {1}", item.Key, 
        item.Value.StudentName);
}

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

Key: 1, Value: John
Key: 2, Value: Steve
Key: 3, Value: Bill
Key: 4, Value: Ram
Key: 5, Value: Ron

Hình dưới đây cho thấy studentDict trong ví dụ trên chứa cặp khóa-giá trị, trong đó khóa là StudentID và giá trị là đối tượng Student.

ToDictionary trong LINQ
Lưu ý: Phương thức ToDictionary không hỗ trợ  cú pháp truy vấn 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.