Sự khác biệt giữa “LINQ thành thực thể”, “LINQ thành SQL” và “LINQ thành tập dữ liệu”


91

Tôi đã làm việc khá lâu với LINQ. Tuy nhiên, vẫn còn một chút bí ẩn về sự khác biệt thực sự giữa các hương vị được đề cập của LINQ.

Câu trả lời thành công sẽ có một sự khác biệt ngắn giữa chúng. Mục tiêu chính của mỗi hương vị là gì, lợi ích là gì và có tác động đến hiệu suất không ...

Tái bút: Tôi biết rằng có rất nhiều nguồn thông tin trên mạng, nhưng tôi đang tìm kiếm một loại "bảng gian lận" hướng dẫn cho một người mới tham gia vào mục tiêu cụ thể.


Câu trả lời:


110
  • tất cả chúng đều là LINQ - Truy vấn tích hợp ngôn ngữ - vì vậy chúng đều có rất nhiều điểm chung. Tất cả các "phương ngữ" này về cơ bản cho phép bạn thực hiện lựa chọn dữ liệu theo kiểu truy vấn, từ nhiều nguồn khác nhau.

  • Linq-to-SQL là nỗ lực đầu tiên của Microsoft đối với ORM - Object-Relational Mapper. Nó chỉ hỗ trợ SQL Server. Đó là một công nghệ ánh xạ để ánh xạ các bảng cơ sở dữ liệu SQL Server với các đối tượng .NET.

  • Linq-to-Entities cũng là một ý tưởng, nhưng sử dụng Entity Framework trong nền, làm ORM - lại từ Microsoft, nhưng hỗ trợ nhiều phụ trợ cơ sở dữ liệu

  • Linq-to-DataSets là LINQ, nhưng việc sử dụng là chống lại DataSets ADO.NET 2.0 "kiểu cũ" - trong thời gian trước ORM của Microsoft, tất cả những gì bạn có thể làm với ADO.NET là trả về DataSets, DataTables, v.v. và Linq -to-DataSets truy vấn các kho dữ liệu đó để lấy dữ liệu. Vì vậy, trong trường hợp này, bạn sẽ trả về DataTable hoặc DataSets (không gian tên System.Data) từ chương trình phụ trợ cơ sở dữ liệu và sau đó truy vấn chúng bằng cú pháp LINQ


1
Xin chúc mừng với 50k, bạn đã chính thức dành quá nhiều thời gian cho StackOverflow. ;)
Aaronaught

1
@Aaronaught: cảm ơn - và bạn hoàn toàn đúng! :-) Phải để lại một cơn nghiện cho mỗi người đàn ông, không? Xin vui lòng?!?!?!
marc_s

1
marc_s, cảm ơn vì câu trả lời này. Bạn có thể cho biết một số điều về hiệu suất. Từ câu trả lời của bạn, tôi sẽ đoán rằng Linq-to-Entities là tiên tiến nhất và do đó có thể hoạt động tốt nhất?
Marcel

2
@Marcel: từ ruột của tôi (không có dữ kiện khó khăn), tôi muốn nói: Linq-to-SQL hoặc là nhanh nhất (chỉ có một lớp giữa cơ sở dữ liệu và mô hình đối tượng), Linq-to-Dataset một giây gần kề và Linq-to -Entities là cuối cùng, vì Entity Framework luôn có hai lớp ánh xạ (do đó phức tạp nhất). Nhưng một lần nữa: chỉ là cảm giác ruột, không có con số nào để hỗ trợ điều đó
marc_s

3
@marc_s Tôi biết đây là một bài đăng cũ, nhưng LINQ cho Thực thể có thể sẽ nhanh hơn LINQ cho Tập dữ liệu trong hầu hết các trường hợp. LINQ to Dataset không thực sự là một kiểu, nó là LINQ trên Object mà bạn đang sử dụng dataset làm đối tượng. Vì LINQ trên các đối tượng không thực hiện bất kỳ SQL nào, trước tiên bạn phải tạo Tập dữ liệu của mình từ nguồn SQL và LINQ trên các đối tượng không thể giúp bạn thực hiện bất kỳ tối ưu hóa truy vấn nào khi truy xuất dữ liệu vào tập dữ liệu. Điều đó và các bộ dữ liệu có hiệu suất khủng khiếp khôn ngoan vì tất cả các cột đều được đóng hộp và tất cả các loại chuyển đổi kiểu đó sẽ giết chết hiệu suất.
Robert McKee

38

LINQ là một tập hợp rộng rãi các công nghệ, dựa trên (ví dụ) một cú pháp hiểu truy vấn, ví dụ:

var qry = from x in source.Foo
          where x.SomeProp == "abc"
          select x.Bar;

được ánh xạ bởi trình biên dịch thành mã:

var qry = source.Foo.Where(x => x.SomeProp == "abc").Select(x => x.Bar);

và ở đây điều kỳ diệu thực sự bắt đầu. Lưu ý rằng chúng tôi chưa nói những gì Fooở đây - và trình biên dịch không quan tâm! Miễn là nó có thể giải quyết một số phương thức phù hợp được gọi là Wherecó thể lấy lambda, và kết quả của việc đó có một số Select phương thức có thể chấp nhận lambda, đó là điều hạnh phúc.

Bây giờ xem xét rằng lambda có thể được biên soạn hoặc vào một phương pháp vô danh (đại biểu, cho LINQ-to-Đối tượng, trong đó bao gồm LINQ-to-DataSet), hoặc để một biểu thức cây (một mô hình runtime đại diện cho lambda trong một mô hình đối tượng ).

Đối với dữ liệu trong bộ nhớ (thông thường IEnumerable<T>), nó chỉ thực thi ủy quyền - tốt và nhanh chóng. Nhưng IQueryable<T>đối với biểu diễn đối tượng của biểu thức (a LambdaExpression<...>), nó có thể tách nó ra và áp dụng nó cho bất kỳ ví dụ "LINQ-to-Something" nào.

Đối với cơ sở dữ liệu (LINQ-to-SQL, LINQ-to-Entities), điều này có thể có nghĩa là viết TSQL, ví dụ:

SELECT x.Bar
FROM [SomeTable] x
WHERE x.SomeProp = @p1

Nhưng nó có thể (ví dụ: đối với Dịch vụ dữ liệu ADO.NET) có nghĩa là viết một truy vấn HTTP.

Việc thực thi một truy vấn TSQL được viết tốt trả về một lượng nhỏ dữ liệu sẽ nhanh hơn việc tải toàn bộ cơ sở dữ liệu qua mạng và sau đó lọc tại máy khách. Tuy nhiên, cả hai đều có kịch bản lý tưởng và kịch bản sai lầm.

Mục tiêu và lợi ích ở đây là cho phép bạn sử dụng một cú pháp duy nhất, được kiểm tra tĩnh để truy vấn nhiều nguồn dữ liệu và làm cho mã biểu cảm hơn (ví dụ: mã "truyền thống" để nhóm dữ liệu không rất rõ ràng về những gì nó đang cố gắng làm - nó bị mất trong khối lượng mã).


Marc, cảm ơn vì cái nhìn sâu sắc này. Tuy nhiên, tôi đã không hỏi về nội bộ chi tiết như vậy. -1, Tôi xin lỗi, vì nó không trả lời câu hỏi.
Marcel

7
Là một người viết nhà cung cấp LINQ của riêng mình, đây là câu trả lời tốt nhất mà tôi đã thấy cho đến nay. Tôi không đồng ý về -1.
Dan Barowy

30

LINQ là viết tắt của truy vấn tích hợp ngôn ngữ. Nó cho phép bạn sử dụng ngôn ngữ truy vấn "kiểu SQL" trực tiếp trong C # để trích xuất thông tin từ các nguồn dữ liệu.

  • Nguồn dữ liệu đó có thể là cơ sở dữ liệu máy chủ SQL - đây là Linq to SQL
  • Nguồn dữ liệu đó có thể là ngữ cảnh dữ liệu của các đối tượng khung thực thể - Linq tới các thực thể .
  • Nguồn dữ liệu đó có thể là các tập dữ liệu ADO.net - Linq to Dataset .

Nguồn dữ liệu đó cũng có thể là một tệp XML - Linq to XML .
Hoặc thậm chí chỉ là một lớp Collection của các đối tượng thuần túy - Linq to Objects .

LINQ mô tả công nghệ truy vấn, phần còn lại của tên mô tả nguồn dữ liệu đang được truy vấn.

Để có thêm một chút thông tin cơ bản:

Tập dữ liệu là các đối tượng ADO.net nơi dữ liệu được tải từ cơ sở dữ liệu vào Tập dữ liệu .net và Linq có thể được sử dụng để truy vấn dữ liệu đó sau khi được tải.

Với Linq to SQL, bạn xác định các lớp .net ánh xạ tới cơ sở dữ liệu và Linq-to-SQL sẽ chăm sóc tải dữ liệu từ cơ sở dữ liệu máy chủ SQL

Và cuối cùng, khung thực thể là một hệ thống nơi bạn có thể xác định cơ sở dữ liệu và ánh xạ đối tượng trong XML, sau đó có thể sử dụng Linq để truy vấn dữ liệu được tải qua ánh xạ này.


3
thực sự, Linq-to-SQL chỉ là SQL Server - không chỉ là phần phụ trợ cơ sở dữ liệu SQL "bất kỳ".
marc_s

3
@marc_s: Tốt. Cảm ơn. Mặc dù, nếu bất kỳ ai quan tâm, có các nhà cung cấp Linq to sql bên thứ 3 cho các cơ sở dữ liệu khác nếu bạn muốn. Xem code2code.net/DB_Linq hoặc Google cho những người khác. Tôi không thể bình luận về chất lượng của chúng.
Simon P Stevens

1
Simon, đặc biệt cảm ơn vì bản tóm tắt 2 dòng hữu ích đó về khung Entitiy. +1
Marcel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.