2009-09-01 31 views
27

Tôi muốn lọc kết quả của mình để chỉ lấy số lượng bản ghi X. Tôi tự hỏi làm thế nào để Take() làm việc?LINQ Take() question

Trên trang web này, tôi tìm thấy: http://www.hookedonlinq.com/TakeOperator.ashx

Nó nói Take() "Ném một ArgumentNullException nếu nguồn là null." Vậy tôi nên làm gì đây? Tôi không thể đảm bảo rằng mỗi khi tôi làm một Take() tôi sẽ có một số hồ sơ trong bảng đó hay không.

Vì vậy, trước tiên tôi có phải đếm không? Sau đó thực hiện một truy vấn khác để đảm bảo có một số bản ghi để lấy?

Ngoài ra điều gì sẽ xảy ra nếu tôi có bản ghi Take (2) nhưng chỉ 1 sẽ ném cùng ngoại lệ này?

Trả lời

42

Có sự khác biệt giữa tham chiếu null và bộ sưu tập trống. Bạn có thể gọi cho Take trên một bộ sưu tập trống. Và đối số chỉ định số lượng tối đa cần thực hiện, vì vậy cũng tốt khi chỉ định nhiều hơn các mục trong bộ sưu tập.

Tôi khuyên bạn nên tham khảo MSDN để biết chi tiết chính xác như thế này.

Đối với LINQ to Objects: http://msdn.microsoft.com/en-us/library/bb503062.aspx

Đối với Liên kết đến cơ sở dữ liệu: http://msdn.microsoft.com/en-us/library/bb300906.aspx

+0

Có đi để làm cho nó mất tất cả kết quả hoặc hạn chế số lượng kết quả? Giống như chỉ phụ thuộc vào các điều kiện nhất định, tôi muốn giới hạn số lượng kết quả hoặc tôi sẽ phải tách rời nhau (tức là với các phương pháp khác nhau)? – chobo2

+1

@ chobo2: Đó là chính xác những gì nó đã làm. Nếu bạn yêu cầu 5 mục nhưng nó chỉ có 3, nó sẽ cung cấp cho bạn tất cả 3. –

9

Đó là null tham khảo hợp ngoại lệ là chỉ khi bạn đang làm điều đó chống lại một nguồn đối tượng như:

List<MyObject> myList = null; 
myList.Take(5); // this would produce the error, of course 

Khi bạn đang làm LINQ to SQL nó sẽ trả về một bảng liệt kê EMPTY của dữ liệu của bạn, không phải là một tham chiếu null. Trên cùng một mã thông báo, nếu bạn đang cố gắng thực hiện nhiều hơn khả dụng, nó sẽ chỉ chiếm số tiền có sẵn. Tôi sử dụng phương pháp này để dữ liệu trang trong một số trường hợp và chắc chắn rất nhiều thời gian khi tôi sẽ yêu cầu nhiều hồ sơ hơn danh sách có sẵn.

+0

Gọi bất kỳ phương thức nào trên 'null' sẽ ném một NullReferenceException. ArgumentNullException sẽ bị ném nếu bạn gọi Take là một phương thức tĩnh: 'List list = null; Enumerable.Take (danh sách, 5); ' – knittl

2

Thực hiện thông qua ngoại lệ nếu đối tượng gọi nó là rỗng. Rất có thể bạn sẽ không có một đối tượng null, và không có hoặc ít hàng không giống nhau (tôi chắc chắn bạn hiểu ngữ nghĩa).

Nếu bạn đang sử dụng một LINQ to bối cảnh SQL và truy vấn trong thời trang của

Context.MyTable.Where(x => x.ID > 0).Take(2); 

trong trường hợp của Where trở về không có kết quả, bạn sẽ không có được một ngoại lệ null, vì truy vấn của bạn chưa được thực hiện, sau đó trong trường hợp nó chỉ chứa 1 kết quả, bạn sẽ chỉ nhận được 1 kết quả trở lại. Take giới hạn số lượng bản ghi trả về.

+0

" trong trường hợp kết quả trả về không, bạn sẽ không nhận được ngoại lệ null, vì truy vấn của bạn chưa được thực hiện "- Không.Bạn sẽ không nhận được một ngoại lệ null vì nếu 'Where' không trả về kết quả nào, nó trả về một tham chiếu không null cho một đối tượng biểu diễn một chuỗi rỗng. –

0

Đếm số lượng các mục trước khi bạn Take():

List<string> a = new List<string>(); 
      int count = a.Count > 12 ? 12 : a.Count; 
      a.Take(count); 
+0

Điều này là không cần thiết. Từ [tài liệu] (https://msdn.microsoft.com/en-us/library/bb503062 (v = vs.110) .aspx): "' Hãy 'liệt kê' nguồn' và tạo các phần tử cho đến khi 'đếm' các phần tử đã được sinh ra hoặc 'nguồn' không chứa thêm phần tử nào. Nếu' count' vượt quá số phần tử trong 'nguồn', tất cả các phần tử của' nguồn' được trả về. " –

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