2008-10-18 34 views
228

LINQ là một trong những cải tiến lớn nhất đối với .NET kể từ khi Generics và nó giúp tôi tiết kiệm rất nhiều thời gian và các dòng mã. Tuy nhiên, cú pháp thông thạo dường như tự nhiên hơn tôi nhiều so với cú pháp biểu thức truy vấn.LINQ - Biểu thức truy vấn thông thạo và truy vấn - Có bất kỳ lợi ích nào của người khác không?

var title = entries.Where(e => e.Approved) 
    .OrderBy(e => e.Rating).Select(e => e.Title) 
    .FirstOrDefault(); 

var query = (from e in entries 
      where e.Approved 
      orderby e.Rating 
      select e.Title).FirstOrDefault(); 

Có sự khác biệt nào giữa hai hoặc có bất kỳ lợi ích cụ thể nào giữa hai loại khác không?

+36

Tôi nghĩ cách câu hỏi là hỏi là khá mang tính xây dựng. Nói rằng không phải vì câu trả lời là * không phải là * thực ra là phần * không xây dựng * nhất của trang này. –

+0

Đối với các truy vấn phức tạp, tôi thấy cú pháp lambda dễ hiểu hơn/dễ đọc hơn, nhưng cú pháp truy vấn chỉ đơn giản là đẹp hơn. – nawfal

+2

Đây là câu hỏi mang tính xây dựng một cách chính xác vì câu trả lời là cả hai đều tương đương nhau. Tôi đọc câu hỏi như yêu cầu nếu có bất kỳ cân nhắc bên cạnh ưu tiên cú pháp để chọn một trong những khác. Đây là thông tin quan trọng cần biết về LINQ. –

Trả lời

225

Không tốt hơn: chúng phục vụ các nhu cầu khác nhau. Cú pháp truy vấn đi vào riêng của nó khi bạn muốn tận dụng nhiều biến phạm vi. Điều này xảy ra trong ba tình huống:

  • Khi sử dụng các từ khóa let
  • Khi bạn có nhiều máy phát điện (từ khoản)
  • Khi làm gia nhập

Dưới đây là một ví dụ (từ LINQPad mẫu):

string[] fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" }; 

var query = 
    from fullName in fullNames 
    from name in fullName.Split() 
    orderby fullName, name 
    select name + " came from " + fullName; 

Bây giờ so sánh điều này với sa cú pháp của tôi trong phương thức:

var query = fullNames 
    .SelectMany (fName => fName.Split().Select (name => new { name, fName })) 
    .OrderBy (x => x.fName) 
    .ThenBy (x => x.name) 
    .Select (x => x.name + " came from " + x.fName); 

Cú pháp phương pháp hiển thị đầy đủ các toán tử truy vấn và ngắn gọn hơn với các truy vấn đơn giản. Bạn có thể tận dụng tối đa cả hai thế giới bằng cách trộn cú pháp truy vấn và phương thức. Điều này thường được thực hiện trong các truy vấn LINQ to SQL:

var query = 
    from c in db.Customers 
    let totalSpend = c.Purchases.Sum (p => p.Price) // Method syntax here 
    where totalSpend > 1000 
    from p in c.Purchases 
    select new { p.Description, totalSpend, c.Address.State }; 
+1

Câu trả lời hay. Bạn có thể cho tôi biết thêm một chút về những gì ".Select (name => new {name, fName})" đang hoạt động không? – quillbreaker

+10

Nó chọn từ riêng lẻ (anne, williams, john, v.v.) cùng với tên đầy đủ trong một loại ẩn danh. Điều này cho phép bạn "mang" tên đầy đủ ban đầu để bạn có quyền truy cập vào cả tên đầy đủ và từ riêng lẻ trong phần còn lại của truy vấn. –

7

Cú pháp lưu loát có vẻ mạnh mẽ hơn, nó cũng sẽ hoạt động tốt hơn để tổ chức mã thành các phương pháp có thể tái sử dụng nhỏ.

12

Giao diện thông thạo nếu chỉ có một nơi. Nếu tôi cần một lựa chọn hoặc orderby, tôi thường sử dụng cú pháp truy vấn.

3

Tôi thực sự thích cú pháp lưu loát và tôi cố gắng sử dụng nó ở nơi có thể, nhưng trong một số trường hợp, ví dụ như tôi sử dụng kết nối, tôi thường thích cú pháp truy vấn hơn. Tôi nghĩ một số người quen thuộc hơn với cú pháp Truy vấn (giống SQL), hơn là lambdas.

3

Mặc dù tôi hiểu và thích định dạng thông thạo, tôi đã gặp khó khăn trong Truy vấn vì lý do dễ đọc. Những người vừa được giới thiệu với LINQ sẽ tìm thấy truy vấn dễ đọc hơn nhiều.

26

Mỗi kiểu có ưu và khuyết điểm của chúng. Cú pháp truy vấn đẹp hơn khi nói đến kết nối và nó có từ khóa hữu ích let giúp việc tạo các biến tạm thời bên trong một truy vấn trở nên dễ dàng.

Cú pháp thông thạo, mặt khác có nhiều phương thức và hoạt động không được hiển thị thông qua cú pháp truy vấn. Cũng vì chúng chỉ là các phương pháp mở rộng mà bạn có thể tự viết.

Tôi đã thấy rằng mỗi lần tôi bắt đầu viết một câu lệnh LINQ bằng cú pháp truy vấn, tôi phải đặt nó vào dấu ngoặc đơn và quay trở lại sử dụng các phương thức mở rộng LINQ thông thạo. Cú pháp truy vấn không có đủ các tính năng để sử dụng.

+0

"vì chúng chỉ là các phương pháp mở rộng mà bạn có thể tự viết." - bạn sẽ gặp phải vấn đề này? http://stackoverflow.com/a/3850254/1175496 –

52

Tôi thích sử dụng sau (đôi khi được gọi là "cú pháp hiểu truy vấn") khi tôi có thể viết toàn bộ biểu thức theo cách đó.

var titlesQuery = from e in entries 
        where e.Approved 
        orderby e.Rating 
        select e.Titles; 

var title = titlesQuery.FirstOrDefault(); 

Ngay sau khi tôi phải thêm (dấu ngoặc đơn) và .MethodCalls(), tôi thay đổi.

Khi tôi sử dụng trước đây, tôi thường đặt một khoản mỗi dòng, như thế này:

var title = entries 
    .Where (e => e.Approved) 
    .OrderBy (e => e.Rating) 
    .Select (e => e.Title) 
    .FirstOrDefault(); 

Tôi thấy rằng một chút dễ dàng hơn để đọc.

3

Tôi thích cú pháp truy vấn khi tôi đến từ lập trình web truyền thống bằng SQL. Nó dễ dàng hơn nhiều để tôi quấn quanh đầu tôi. Tuy nhiên, nó nghĩ rằng tôi sẽ bắt đầu sử dụng .Where (lambda) vì nó chắc chắn là ngắn hơn nhiều.

13

Tôi hoàn toàn không nhận được cú pháp truy vấn. Không có lý do nào cho nó trong đầu tôi. cho phép có thể đạt được với. Chọn và các loại ẩn danh. Tôi chỉ nghĩ rằng mọi thứ trông được tổ chức hơn nhiều với "dấu câu" trong đó.

+8

Nhiều lần tham gia có thể khá mất thời gian khá nhanh với cú pháp thông thạo. Tôi thường sử dụng thông thạo bản thân mình mặc dù - trừ khi tham gia có liên quan. –

+0

@Instance Hunter: Tương tự ở đây. Tôi đã mất khá nhiều thời gian để bắt đầu nắm bắt ý tưởng về cú pháp thông thạo. Kết hợp với khả năng liệt kê mạnh mẽ và ý tưởng về các hàm "thuần túy", giờ đây tôi thực sự thích nó, và trước đây là những tình huống phức tạp mà không có biểu diễn mã đẹp. Đối với phần ye-ole-SQL của bộ não, nó vẫn là một phước lành để có cú pháp truy vấn. –

3

Tôi đã sử dụng Linq trong khoảng 6 tháng nay. Khi tôi lần đầu tiên bắt đầu sử dụng nó, tôi ưa thích cú pháp truy vấn vì nó rất giống với T-SQL.

Nhưng, tôi đang dần dần đi đến vòng trước đây, vì nó dễ dàng để viết khối có thể tái sử dụng mã như phương pháp mở rộng và chỉ chuỗi chúng lại với nhau. Mặc dù tôi thấy việc đặt từng mệnh đề trên một dòng riêng của nó sẽ giúp rất nhiều với khả năng đọc.

4

Tôi biết câu hỏi này được gắn thẻ với C#, nhưng cú pháp thông thạo là đau đớn tiết ra với VB.NET.

2

Tôi vừa thiết lập các tiêu chuẩn của công ty mình và chúng tôi thực thi việc sử dụng các phương pháp Mở rộng. Tôi nghĩ rằng nên chọn một cái khác và không trộn chúng lên trong mã. Các phương thức mở rộng đọc giống như các mã khác.

Cú pháp hiểu không có tất cả các toán tử và sử dụng dấu ngoặc đơn xung quanh truy vấn và thêm các phương thức mở rộng sau khi tất cả chỉ cầu xin tôi sử dụng các phương thức mở rộng ngay từ đầu.

Nhưng phần lớn nó chỉ là sở thích cá nhân với một vài ngoại lệ.

+3

Tôi sẽ không thực thi các sở thích cá nhân .. Nhưng đó là tôi. –

18

Trong VB.NET tôi rất thích cú pháp truy vấn.

Tôi ghét phải lặp lại xấu xí Function -từ khoá:

Dim fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" }; 
Dim query = 
    fullNames.SelectMany(Function(fName) fName.Split(). 
    Select(Function(Name) New With {Name, fName})). 
    OrderBy(Function(x) x.fName). 
    ThenBy(Function(x) x.Name). 
    Select(Function(x) x.Name & " came from " & x.fName) 

truy vấn gọn gàng này là nhiều hơn nữa có thể đọc được và duy trì theo ý kiến ​​của tôi:

query = From fullName In fullNames 
     From name In fullName.Split() 
     Order By fullName, name 
     Select name & " came from " & fullName 

cú pháp truy vấn VB.NET cũng mạnh mẽ hơn và ít tiết hơn so với trong C#: https://stackoverflow.com/a/6515130/284240

Ví dụ truy vấn LINQ to DataSet (đối tượng)

VB.NET:

Dim first10Rows = From r In dataTable1 Take 10 

C#:

var first10Rows = (from r in dataTable1.AsEnumerable() 
        select r) 
        .Take(10); 
+7

Sự đồng cảm của tôi đối với những nhà phát triển VB không thể sử dụng kiểu truy vấn. – nawfal

+4

... hoặc ngừng sử dụng VB ... :) – enorl76

+1

Ví dụ C# cuối cùng của bạn quá đơn giản để có giá trị: bạn chỉ cần viết 'dataTable1.AsEnumerable(). Take (10); – Emyr

Các vấn đề liên quan