2009-03-10 31 views
54

Tôi bắt đầu sử dụng LINQ nói chung (cho đến nay toXML và toSQL). Tôi đã thấy rằng đôi khi có hai hoặc nhiều cách để đạt được kết quả tương tự. Hãy ví dụ đơn giản này, theo như tôi hiểu cả hai quay trở lại chính xác những điều tương tự:LINQ: Ký hiệu Dot và Biểu thức truy vấn

SomeDataContext dc = new SomeDataContext(); 

var queue = from q in dc.SomeTable 
     where q.SomeDate <= DateTime.Now && q.Locked != true 
     orderby (q.Priority, q.TimeCreated) 
     select q; 

var queue2 = dc.SomeTable 
     .Where(q => q.SomeDate <= DateTime.Now && q.Locked != true) 
     .OrderBy(q => q.Priority) 
     .ThenBy(q => q.TimeCreated); 

Bên cạnh bất kỳ sai lầm tôi có thể đã được thực hiện trong cú pháp hoặc một tham số thiếu hoặc khác biệt, ý tưởng là có hai cách để thể hiện cùng một điều; Tôi hiểu rằng phương pháp đầu tiên có một số hạn chế và rằng "ký hiệu chấm" hoàn chỉnh hơn, nhưng bên cạnh đó, có bất kỳ lợi thế nào khác không?

+0

Cảm ơn mọi người đã trả lời. Than ôi, tôi chỉ có thể đánh dấu một câu trả lời đúng. Nhưng tôi đánh giá cao tất cả các ý kiến. –

+1

Nhân bản: http://stackoverflow.com/questions/214500/which-linq-syntax-do-you-prefer-fluent-or-query-expression – Mikhail

Trả lời

48

Ký hiệu "dấu chấm" thường được gọi là cú pháp Lambda. Ký pháp đầu tiên đi theo một số tên nhưng tôi thường gọi nó là cú pháp truy vấn.

Tôi làm việc cho một nhóm gồm 10 nhà phát triển và chúng tôi tranh luận về độ dài mà chúng tôi nên sử dụng làm tiêu chuẩn. Nói chung, các nhà phát triển dày dạn hơn (với LINQ) di chuyển theo cú pháp Lambda nhưng có những ngoại lệ đáng kể.

Lambda ngắn gọn hơn nhưng thực hiện nhiều lần tham gia bảng là một cơn ác mộng. Tham gia chỉ sạch hơn với cú pháp truy vấn. Mặt trái là có một số hoạt động LINQ chỉ tồn tại trong cú pháp Lambda: Đơn(), Đầu tiên(), Đếm() v.v.

Vì vậy, hãy sử dụng những gì bạn cảm thấy thoải mái nhất và nhận ra rằng bạn có được kinh nghiệm, sở thích của bạn có thể sẽ thay đổi. Có giá trị lớn trong việc có thể đọc cả hai và chắc chắn sẽ có những tình huống mà bạn phải sử dụng một chút của cả hai. Các tình huống khác sẽ cho họ vay theo một phong cách khác. Cuối cùng, tất cả đều được dịch sang cùng một mã thực thi.

+1

5 năm sau và cú pháp lambda phương pháp xích bây giờ thường được gọi là [Giao diện thông thạo] (http://en.wikipedia.org/wiki/Fluent_interface). – Nick

8

Vâng, ký hiệu 'chấm' có thể ngắn hơn nhiều. Đi:

var result = from p in dc.Products 
      where p.Id > 5 
      select p; 

hay:

var result = dc.Products.Where(p => p.Id > 5); 

tôi thích sau này vì nó là ngắn hơn nhiều, và dễ đọc hơn.

+0

Khi sử dụng LINQ to SQL, tôi thích cái cũ hơn vì nó gần với T- SQL (có ích khi viết các truy vấn DB) và sau này cho các truy vấn LINQ khác (như LINQ to XML). – RobS

+0

Có, bạn có một điểm ở đó. Với linq2sql tôi thường sử dụng phiên bản đầu tiên, cho cùng một lý do bạn đề cập đến. Mặc dù tôi cũng phải thừa nhận rằng đối với các truy vấn rất đơn giản như ở trên, tôi thường sử dụng phiên bản thứ hai, ngắn, chỉ vì tôi lười :-) – Razzie

+0

Không phải lúc nào cũng ngắn hơn và đôi khi khó đọc hơn, nhưng bạn có chỉ ra rằng nó có thể ngắn hơn một chút. –

2

Chúng biên dịch thành cùng một mã, hoặc thay vào đó mã đầu tiên được dịch thành mã thứ hai và sau đó được biên dịch.

Bạn đúng rằng sự khác biệt là phiên bản đầu tiên sạch hơn nhưng bị hạn chế hơn. Trong ví dụ thứ hai, bạn có thể sử dụng các đại biểu hiện có, ví dụ:

Func<int, bool> isEven = i => i%2 == 0; 
Enumerable.Range(10).Where(isEven).ToList().ForEach(Console.WriteLine); 
+0

Không hoàn toàn đúng. Bạn có thể sử dụng vẫn còn sử dụng một đại biểu exisiting, ví dụ: var result = from s trong danh sách where isEven.Invoke (s.Length) select s; – Razzie

+0

có, nhưng nói về phong cách * .Invoke chỉ đơn giản là xấu xí :) – user76035

+1

bạn không cần phải sử dụng Gọi, điều này chỉ hoạt động tốt: var result = from i in ints where isEven (i) select i; – theburningmonk

27

Tôi sử dụng bất kỳ cú pháp nào có thể đọc được nhiều hơn cho truy vấn của mình, trên từng trường hợp cụ thể.

Nếu có thể, tôi cố gắng tránh trộn và kết hợp cả hai, mặc dù đôi khi không sao (nếu đó chỉ là một cuộc gọi đến First() ở cuối truy vấn). thực hiện chậm có nghĩa là nó cũng giống như hiệu quả sử dụng một biểu thức truy vấn và gán kết quả cho một biến, và sau đó sử dụng ký hiệu dấu chấm sử dụng rằng biến:

var query = from x in y 
      orderby z 
      group x by x.Name into groups 
      // etc 
      select foo; 

var page = query.Skip(50).Take(10); 

Như những người khác đã nói, biểu thức truy vấn chỉ là dịch sang " bình thường "C# 3 không có biểu thức truy vấn, do đó, không có hình phạt cho việc này.

+3

+1 một lần nữa để tách hai khi bạn muốn sử dụng chúng cùng nhau hơn là gói đầu tiên trong dấu ngoặc đơn và phần còn lại vào cuối. – Shibumi

3

Tôi tìm thấy cặp ký hiệu Lambda và súc tích hơn.Tôi chỉ thấy khó chịu rằng nếu bạn có biểu thức Lambda ở bất kỳ nơi nào bên trong cuộc gọi phương thức, bạn không thể sửa đổi mã khi đang bay trong chế độ gỡ lỗi ...

+0

Chỉnh sửa & Tiếp tục có hoạt động nếu bạn đang sử dụng biểu thức truy vấn không? –

+0

@MichaelFreidgeim - No. :-) Một trong những điều tôi phát hiện ra trong 2 năm kể từ khi viết câu trả lời này. –

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