Ngôn ngữ LINQ - Toán tử where
Toán tử lọc Where trong 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ệnh đề where trong cú pháp truy vấn LINQ
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;
}
Phương thức Where trong cú pháp phương thức LINQ
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
Nhiều mệnh đề 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)
.
Những điểm cần nhớ về toán tử Where:
- Where được sử dụng để lọc danh sách dựa trên các tiêu chí nhất định.
- Phương thức mở rộng
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. - Cú pháp phương thức LINQ yêu cầu toàn bộ biểu thức lambda trong phương thức mở rộng
Where
trong khi cú pháp truy vấn chỉ yêu cầu phần thân biểu thức lambda. - Có thể sử dụng nhiều mệnh đề
where
hoặc phương thức mở rộngWhere
trong một truy vấn LINQ duy nhất.