LINQ dùng để truy vấn dữ liệu từ cơ sở dữ liệu và các collection, chúng ta sử dụng IEnumerable và IQueryable để thao tác dữ liệu nhưng một số bạn vẫn chưa hiểu được sự khác nhau giữa 2 đối tượng này. IQueryable kế thừa IEnumerable, vì thế IQueryable có tất cả các đặc tính của IEnumerable và có thêm các đặc tính của riêng nó. Cả hai đều mang tính quan trọng khi truy vấn và thao tác dữ liệu. Chúng ta hãy cùng xem các tính năng của cả hai và so sánh chúng để dùng trong trường hợp nào cho hợp lý nhất nhé.
Contents
IEnumerable
- IEnumerable nằm trong namespace System.Collections
- IEnumerable có thể duyệt cac phần tử chỉ 1 chiều tiến lên, nó không thể duyệt ngược lại giữa các phần tử.
- IEnumerable tốt nhất khi truy vấn từ một collection in-memory tức là trong bộ nhớ RAM như List, Array…
- Khi truy vấn dữ liệu từ database, IEnumerable thực thi câu lệnh select trên server sau đó tải toàn bộ dữ liệu về client rồi mới lọc dữ liệu.
- IEnumerable phù hợp với Linq to Object và Linq to XML
- IEnumerable không hỗ trợ custom query
- IEnumerable không hỗ trợ lazy loading vì thế không phù hợp với trường hợp phân trang.
Ví dụ về IEnumerable
MyDataContext dc = new MyDataContext ();
IEnumerable<Employee> list = dc.Employees.Where(p => p.Name.StartsWith("S"));
list = list.Take<Employee>(10);
Câu lệnh của đoạn code trên sẽ gen ra như sau:
SELECT [t0].[EmpID], [t0].[EmpName], [t0].[Salary] FROM [Employee] AS [t0]
WHERE [t0].[EmpName] LIKE @p0
Chú ý là trong câu lệnh này “top 10” sẽ không có vì IEnumerable lọc các bản ghi ở dưới client. Nên toàn bộ số bản ghi trước khi load ra top 10 sẽ dc tải về client.
IQueryable
- IQueryable nằm trong namespace System.Linq
- IQueryable cũng chỉ có thể di chuyển 1 chiều tiến lên trong collection, nó không thể move back lại.
- IQueryable tốt nhất cho truy vấn dữ liệu out-memory như là database.
- Khi truy vấn, IQueryable thực thi câu lệnh truy vấn và lọc dữ liệu trên Server luôn
- IQueryable phù hợp cho Linq to SQL
- IQueryable hỗ trợ custom query sử dụng phương thức CreateQuery và Execute.
- IQueryable hỗ trợ lazy loading. Vì thế nó phù hợp cho trường hợp phân trang.Ví dụ về IQueryable
Ví dụ về IQueryable
MyDataContext dc = new MyDataContext ();
IQueryable<Employee> list = dc.Employees.Where(p => p.Name.StartsWith("S"));
list = list.Take<Employee>(10);
Câu lệnh gen ra sẽ như sau:
SELECT TOP 10 [t0].[EmpID], [t0].[EmpName], [t0].[Salary] FROM [Employee] AS [t0]
WHERE [t0].[EmpName] LIKE @p0
Chú ý: Câu lệnh trên có chữa “top 10” vì IQueryable thực thi câu lệnh và lọc dữ liệu trên server hoàn toàn. Chỉ khi gọi ToList() hoặc đưa vào duyệt thì nó mới thực thi.
Tổng kết
Trong bài viết này mình cố gắng giải thích sự khác nhau giữa IEnumerable và IQueryable. Iqueryable giúp cho các bạn build câu lệnh và thực thi 1 lần trên server để trả về số bản ghi nhỏ nhất có thể. Còn IEnumerable giúp các bạn thao tác với các collection in-memory sẽ tốt hơn. Mình hy vọng sau khi đọc xong bài viết này các bạn có thể tăng khả năng sử dụng 2 đối tượng này giúp tăng performance. Nếu có feedback gì về bài viết vui lòng comment phía dưới.