Hầu hết các lập trình viên phát triển Web theo hướng ASP.NET đều tìm hiểu và sử dụng LINQ, như vậy lý do đó là gì? Bài viết này sẽ giải đáp các lý do tại sao LINQ có nhiều ưu điểm vượt trội hơn so với SQL.
Một trong các lý do hàng đầu để LINQ nhận sự quan tâm lớn chính là nó tích hợp với C# (hay VB), vì vậy giảm thiểu khoảng trống thiếu tương thích giữa các ngôn ngữ lập trình và cơ sở dữ liệu, cũng như cung cấp 1 giao diện truy vấn đơn giản cho tất cả các nguồn dữ liệu. Quan trọng hơn là, khi truy vấn database, LINQ có khả năng thực thi năng suất (xét về mặt bằng chung) tốt hơn so với SQL.
Thật vậy, nếu so sánh với SQL, LINQ đơn giản hơn, gọn hơn và mã nguồn ở cấp độ cao hơn. LINQ đôi khi xem xét để so sánh với C#, C++. SQL là ngôn ngữ truy vấn lâu đời, được phát minh vào năm 1974. Từ đó, SQL được mở rộng dường như vô tận, nhưng lại không được tái cấu trúc lại. Điều đó là cho SQL đôi khi hơi lộn xộn, tương tự như VB6 và Visual FoxPro. Nếu bạn không đồng ý nghĩa điều trên có thể là do bạn đã quá quen thuộc với SQL.
Hãy làm ví dụ để thấy rõ sự so sánh giữa LINQ và SQL. Chúng ta có 1 đoạn SQL đơn giản như sau:
SELECT UPPER(Name) FROM Customer WHERE Name LIKE 'A%' ORDER BY Name
Ví dụ trên bạn cho tất cả tên (Name) của khách hàng bắt đầu từ vần A và xuất kết quả in hoa danh sách tên khách hàng. Nếu bạn cần lấy các record từ database từ dòng 21 đến dòng 30. Bạn cần viết thêm 1 query phụ như sau:
SELECT UPPER(Name) FROM ( SELECT *, RN = row_number() OVER (ORDER BY Name) FROM Customer WHERE Name LIKE 'A%' ) WHERE RN BETWEEN 21 AND 30 ORDER BY Name
Nếu bạn dùng database SQL 2005 trở về trước thì câu truy vấn dài hơn 1 chút:
SELECT TOP 10 UPPER (c1.Name) FROM Customer c1 WHERE c1.Name LIKE 'A%' AND c1.ID NOT IN ( SELECT TOP 20 c2.ID FROM Customer c2 WHERE c2.Name LIKE 'A%' ORDER BY c2.Name ) ORDER BY c1.Name
Mặc dù các câu truy vấn trên không phức tạp, nhưng nó lại vi phạm nguyên lý DRY (DON’T REPEAT YOURSELF tức là KHÔNG LẶP LẠI CHÍNH BẠN). Tiếp đến, chúng ta xét câu lệnh LINQ ngắn gọn, dễ hiểu như sau:
var query = from c in db.Customers where c.Name.StartsWith ("A") orderby c.Name select c.Name.ToUpper(); var thirdPage = query.Skip(20).Take(10);
Chỉ khi nào chúng ta truy xuất biến thirdPage câu truy vấn mới thực thi. Trong trường hợp, LINQ sang SQL hay Entity Framework, cơ chế diễn dịch sẽ chuyển truy vấn (cái mà chúng ta chia thành 2 bước trong ví dụ trên) thành 1 câu SQL tối ưu để truy vấn cơ sở dữ liệu.
Tính khả thi
Bạn có thể quan tâm đến lợi ích tinh tế (nhưng quan trọng) theo hướng tiếp cận LINQ. Chúng ta tạo câu truy vấn trong 2 bước cho phép xây dựng bước thứ 2 vào 1 phương thức có thể tái sử dụng như sau:
IQueryable<T> Paginate<T> (this IQueryable<T> query, int skip, int take) { return query.Skip(skip).Take(take); }
Sau đó, bạn thể viết truy vấn trên như sau:
var query = ... var thirdPage = query.Paginate (20, 10);
Vấn đề quan trọng là chúng ta có thể áp dụng phương thức Paginate với bất kỳ truy vấn nào. Nói cách khác, với LINQ bạn có thể chia câu truy vấn thành nhiều phần, và tái sử dụng các phần truy vấn cho toàn bộ ứng dụng của bạn.
Tính liên kết
Một lợi ích khác của LINQ là bạn có thể truy vấn theo các mối quan hệ mà không cần phải join. Ví dụ, nếu bạn muốn liệt kê danh sách các hóa đơn có giá trị bằng hoặc lớn hơn $1000 của các khách hàng ở Washington. Chúng ta giả định các hóa đơn được liên kết (theo mô hình giữa 1-n giữa hai bảng Purchase và PurchaseItem) và chúng ta muốn bao gồm các hóa đơn tiền mặt (không có tên khách hàng). Để truy vấn, chúng ta dùng 4 bảng Purchase, Customer, Address và PurchaseItem.
Trong LINQ, câu truy vấn được viết như sau:
from p in db.Purchases where p.Customer.Address.State == "WA" || p.Customer == null where p.PurchaseItems.Sum (pi => pi.SaleAmount) > 1000 select p
Trong SQL, câu truy vấn được viết như sau:
SELECT p.* FROM Purchase p LEFT OUTER JOIN Customer c INNER JOIN Address a ON c.AddressID = a.ID ON p.CustomerID = c.ID WHERE (a.State = 'WA' || p.CustomerID IS NULL) AND p.ID in ( SELECT PurchaseID FROM PurchaseItem GROUP BY PurchaseID HAVING SUM (SaleAmount) > 1000 )
Mở rộng thêm ví dụ này, chúng ta muốn các kết quả hiển thị theo thứ tự đảo ngược về giá cả, và tên người bán và số lượng item sản phẩm trong kết quả truy vấn. Chú ý cách tính tự nhiên chúng ta mô tả các tham số mà không cần lặp lại trong LINQ.
from p in db.Purchases where p.Customer.Address.State == "WA" || p.Customer == null let purchaseValue = p.PurchaseItems.Sum (pi => pi.SaleAmount) where purchaseValue > 1000 orderby purchaseValue descending select new { p.Description, p.Customer.SalesPerson.Name, PurchaseItemCount = p.PurchaseItems.Count() }
Đây là đoạn code trong SQL có cùng chức năng:
SELECT p.Description, s.Name, (SELECT COUNT(*) FROM PurchaseItem pi WHERE p.ID = pi.PurchaseID) PurchaseItemCount FROM Purchase p LEFT OUTER JOIN Customer c INNER JOIN Address a ON c.AddressID = a.ID LEFT OUTER JOIN SalesPerson s ON c.SalesPersonID = s.ID ON p.CustomerID = c.ID WHERE (a.State = 'WA' OR p.CustomerID IS NULL) AND p.ID in ( SELECT PurchaseID FROM PurchaseItem GROUP BY PurchaseID HAVING SUM (SaleAmount) > 1000 ) ORDER BY (SELECT SUM (SaleAmount) FROM PurchaseItem pi WHERE p.ID = pi.PurchaseID) DESC
Điểm thú vị là có thể chuyển dịch câu truy vấn trên từ SQL ngược lại thành LINQ, tuy nhiên điều đó mang lại 1 câu truy vấn bị lặp lại đôi chút và hơi rối. Do đó bạn có thể thấy LINQ “tốt hơn” so với SQL ở việc liên kết dữ liệu giữa nhiều thực thể (bảng).
Ngoài ra, còn có nhiều tiêu chí khác để so sánh như về thông số, kiểu tĩnh an toàn, xử lý client, … tuy nhiên chừng này thông tin trong bài viết cũng đủ hình dung những ưu điểm của LINQ so với SQL. Đến đây, chắc hẳn nhiều bạn cho rằng nên vứt bỏ SQL. Hãy bình tĩnh! Thế giới công nghệ lúc nào cũng có 2 mặt, các bài tiếp theo tôi sẽ cho các bạn biết ưu điểm của SQL mà dù lỗi thời các công ty phần mềm buộc phải sử dụng.
- APA:
Dammio. (2017). Tại sao LINQ lại “đánh bại” SQL?. https://www.dammio.com/2017/05/26/tai-sao-linq-lai-danh-bai-sql.
- BibTeX:
@misc{dammio,
author = {Dammio},
title = {Tại sao LINQ lại “đánh bại” SQL?},
year = {2017},
url = {https://www.dammio.com/2017/05/26/tai-sao-linq-lai-danh-bai-sql},
urldate = {2024-09-29}
}
LINQ tốt nè, truy vấn gọn hơn, nhưng hiệu suất chưa chắc ăn SQL
cũng tùy dạng câu truy vấn nhé bạn!
Theo em thì LINQ mặc dù hay và tiện nhưng thực tế ng ta vẫn xài song song 2 SQL và LINQ thì LINQ có 1 vài trường hợp xử lý chậm hơn SQL thông thường
Thế cái db.* ở đâu vậy bạn. Trong trường thì LINQ sử dụng nhiều còn trong cty phần mềm thì SQL sử dụng nhiều.
Biến db là 1 biến kiểu DbContext để mô phỏng database thôi bạn. Như đã nói ở phần kết luận, 1 số câu truy vấn SQL (ADO.NET LINQ) có tốc độ vẫn tốt hơn LINQ. LINQ được cái tiện lợi khi lập trình và thao tác. Ví dụ, câu truy vấn Insert (kể cả Insert Row) thì LINQ tốt hơn, nhưng đối với đọc bảng (read table) thì SQL lại tốt hơn… Đó là lý do khuyến cáo nên dùng song song cả hai một lúc để đảm bảo tương thích về mặt công nghệ, đồng thời tối ưu được… Đọc tiếp »
Chuẩn đấy bạn. Tùy trường hợp mà sử dụng thôi. Với những truy vấn phân trang mà dữ liệu trên 100 000 dòng thì trên trang của MS cũng khuyên là không nên sử dụng. Còn các trường hợp thêm sửa xóa cập nhật thì linq ngon nhất luôn. Cực kì nhanh
Chúc ad sức khỏe nhé!
cảm ơn bạn nhiều nhé, chúc bạn thành công!
Chúc website của bạn nhanh phát triển và thành công!