Các toán tử filtering trong LINQ lọc danh sách dựa trên một số tiêu chí đã được định nghĩa. Bảng sau liệt kê tất cả toán tử lọc có sẵn trong LINQ.
Toán tử | Mô tả |
---|---|
Where | Trả về các phần tử từ danh sách dựa trên biểu thức điều kiện. |
OfType | Trả về các phần tử từ danh sách dựa trên một kiểu được chỉ định. Tuy nhiên, nó sẽ phụ thuộc vào khả năng của chúng để chuyển sang một kiểu cụ thể. |
Toán tử lọc là một trong những toán tử truy vấn chuẩn của LINQ.
Toán tử Where
(một phương thức mở rộng của LINQ) lọc danh sách dựa trên biểu thức điều kiện đã cho và trả về danh sách mới. Các điều kiện có thể là biểu thức lambda hoặc delegate Func.
Phương thức mở rộng Where
sau có hai phương thức quá tải. Cả hai phương thức quá tải đều chấp nhận tham số kiểu delegate Func.
Phương thức quá tải đầu tiên yêu cầu tham số đầu vào là Func<TSource, bool>
và phương thức quá tải thứ hai yêu cầu tham số đầu vào Func<TSource, int, bool>
trong đó int là chỉ mục:
// first
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
// second
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate);
Mẫu truy vấn sau đây sử dụng toán tử Where
để lọc các học sinh tuổi teen (từ 13 - 19 tuổi) từ danh sách học sinh đã cho. Nó sử dụng biểu thức lambda như một hàm vị ngữ.
// 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 teenAgerStudent = from s in studentList
where s.Age > 12 && s.Age < 20
select s;
foreach(Student std in teenAgerStudent)
{
Console.WriteLine(std.StudentName);
}
Đây là kết quả khi biên dịch và thực thi chương trình:
John
Bill
Ron
Trong truy vấn mẫu ở trên, phần thân biểu thức lambda s.Age > 12 && s.Age < 20
được truyền dưới dạng hàm vị ngữ Func<TSource, bool>
để đánh giá mọi học sinh trong danh sách.
Ngoài ra, bạn cũng có thể sử dụng kiểu delegate Func với phương thức ẩn danh để truyền vào dưới dạng hàm vị ngữ như bên dưới (kết quả trả về đều giống nhau):
Func<Student, bool> isTeenAger = delegate(Student s)
{
return s.Age > 12 && s.Age < 20;
};
var filteredResult = from s in studentList
where isTeenAger(s)
select s;
Bạn cũng có thể gọi bất kỳ phương thức nào khớp với tham số Func cho một trong các phương thức Where()
quá tải như ví dụ dưới đây:
public static void Main()
{
var filteredResult = from s in studentList
where IsTeenAger(s)
select s;
}
public static bool IsTeenAger(Student student)
{
return student.Age > 12 && student.Age < 20;
}
Không giống như cú pháp truy vấn, bạn cần truyền toàn bộ biểu thức lambda dưới dạng hàm vị ngữ thay vì chỉ có phần thân biểu thức trong cú pháp phương thức LINQ. Hãy xem ví dụ sau:
// Where extension method in Method Syntax
var filteredResult = studentList.Where(s => s.Age > 12 && s.Age < 20);
Như đã đề cập ở trên, phương thức mở rộng Where
cũng có phương thức quá tải thứ hai bao gồm chỉ mục của phần tử hiện tại trong danh sách. Bạn có thể sử dụng chỉ mục đó trong logic của bạn nếu bạn cần.
Ví dụ sau sử dụng phương thức mở rộng Where
để lọc ra các phần tử ở vị trí lẻ trong danh sách và chỉ trả về các phần tử ở vị trí chẵn. Hãy nhớ rằng chỉ số bắt đầu từ số 0.
IList<Student> studentList = new List<Student>()
{
new Student() { StudentID = 1, StudentName = "John", Age = 18 },
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 },
new Student() { StudentID = 3, StudentName = "Bill", Age = 25 },
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 },
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};
var filteredResult = studentList.Where((s, index) => index % 2 == 0);
foreach (var student in filteredResult)
{
Console.WriteLine(student.StudentName);
}
Đây là kết quả khi biên dịch và thực thi chương trình:
John
Bill
Ron
where
Bạn có thể gọi mệnh đề where
nhiều lần trong một truy vấn LINQ sử dụng cú pháp truy vấn.
// Multiple where clause in Query Syntax C#
var filteredResult = from s in studentList
where s.Age > 12
where s.Age < 20
select s;
Bạn cũng có thể gọi phương thức mở rộng Where()
nhiều lần trong một truy vấn LINQ sử dụng cú pháp phương thức.
// Multiple where clause in Method Syntax C#
var filteredResult = studentList.Where(s => s.Age > 12)
.Where(s => s.Age < 20);
Khi sử dụng nhiều mệnh đề where thì LINQ lọc danh sách kết quả theo thứ tự của các mệnh đề where.
Như ở ví dụ trên, đầu tiên LINQ sẽ lọc ra những học sinh có tuổi lớn hơn 12 sau đó nó tiếp tục lấy những sinh viên đã được lọc ở mệnh đề where đầu tiên để lấy ra những sinh viên có tuổi nhỏ hơn 20.
Hai mệnh đề where trên tương đương với biểu thức sau: where s.Age > 12 && s.Age < 20
hoặc Where(s => s.Age > 12 && s.Age < 20)
.
Where
có hai phương thức quá tải. Sử dụng phương thức quá tải thứ hai để biết chỉ mục của phần tử hiện tại trong danh sách.Where
trong khi cú pháp truy vấn chỉ yêu cầu phần thân biểu thức lambda.where
hoặc phương thức mở rộng Where
trong một truy vấn LINQ duy nhất.Toán tử OfType
lọc danh sách dựa trên khả năng ép kiểu một phần tử trong danh sách thành kiểu được định.
Sử dụng toán tử OfType
để lọc danh sách dựa trên kiểu dữ liệu của từng phần tử.
IList mixedList = new ArrayList();
mixedList.Add(0);
mixedList.Add("One");
mixedList.Add("Two");
mixedList.Add(3);
mixedList.Add(new Student() { StudentID = 1, StudentName = "Bill" });
var stringResult = from s in mixedList.OfType<string>()
select s;
var intResult = from s in mixedList.OfType<int>()
select s;
var stdResult = from s in mixedList.OfType<Student>()
select s;
foreach (var str in stringResult)
{
Console.WriteLine(str);
}
foreach (var integer in intResult)
{
Console.WriteLine(integer);
}
foreach (var std in stdResult)
{
Console.WriteLine(std.StudentName);
}
Đây là kết quả khi biên dịch và thực thi chương trình:
One
Two
0
3
Bill
Bạn có thể sử dụng phương thức mở rộng OfType<TResult>()
trong cú pháp phương thức LINQ như bên dưới:
var stringResult = mixedList.OfType<string>();
Đây là kết quả khi biên dịch và thực thi chương trình:
One
Two
Truy cập MSDN để biết thêm thông tin về các toán tử filtering trong LINQ.
Bạn có thể vui lòng tắt trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi duy trì hoạt động của trang web.
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.
Expression trong LINQ là gì? Cây biểu thức trong LINQ là gì? Cách khai báo và sử dụng chúng trong LINQ.