2015-06-22 18 views
7

Tôi có một bảng khá lớn mà tôi đang truy vấn trong ứng dụng web của mình và tôi chỉ muốn trả lại số hàng N từ bảng.Phương thức Take() hoạt động như thế nào?

Tôi đã đọc qua tài liệu MSDN, nhưng tôi không thể biết vị trí của nó nếu Take() trước hết kéo tất cả bản ghi từ DB hoặc nếu nó hoạt động tương tự như TOP của Máy chủ SQL.

tôi lo lắng nếu Take() sẽ kéo tất cả hồ sơ, và sau đó được đầu N số lượng hồ sơ HOẶC nó sẽ hoạt động như mong đợi và lấy chỉ N số lượng hồ sơ trực tiếp

+0

Bạn có thể sử dụng SQL Profiler để xem SQL nó tạo ra cho chính mình. Giả sử bạn gọi .Take() trên một IQueryable nó sẽ thực hiện một TOP N đối với SQL Server. Tôi luôn sử dụng profiler để đảm bảo rằng LINQ-SQL/Entities tạo ra một nửa SQL khá. – DaveShaw

+0

Điều gì 'Take()' phụ thuộc vào việc bạn đang sử dụng cơ sở dữ liệu nào và cách bạn sử dụng nó. Tất cả những thứ phổ biến tôi đã sử dụng đều làm đúng. –

+1

Bạn đang sử dụng "LINQ" nào? LINQ to SQL? Khuôn khổ thực? –

Trả lời

10

Xem Return Or Skip Elements in a Sequence.

Take(N) sẽ thêm TOP N vào SQL của bạn và chỉ truy xuất các bản ghi N.

Ví dụ (sử dụng riêng tôi SQL Server 2014 với EF 6.1):

LINQ này:

var query = await dbContext.Lookup 
          .Where(w => w.LookupCd == '1') 
          .Take(10) 
          .ToListAsync(); 

Tạo SQL này:

SELECT TOP (10) 
    [Extent1].[LookupId] AS [LookupId], 
    [Extent1].[LookupTypeId] AS [LookupTypeId], 
    [Extent1].[LookupCd] AS [LookupCd], 
    [Extent1].[LookupName] AS [LookupName], 
    [Extent1].[LookupDescription] AS [LookupDescription] 
FROM [dbo].[Lookup] AS [Extent1] 
WHERE '1' = [Extent1].[LookupCd] 

Sử dụng SQL Profiler (nếu bạn đang sử dụng SQL Server) nếu bạn muốn chắc chắn những gì SQL LINQ của bạn được tạo ra. Điều này luôn luôn là một thực hành tốt với bất kỳ LINQ bạn viết.

SQL Profiler

+0

Tôi vừa thử in ra truy vấn var tôi đã viết trong trình soạn thảo, hiển thị nó thông qua Cửa sổ ngay lập tức và chắc chắn đủ nó in ra TOP CHỌN! –

1

Nó sẽ chỉ lấy trực tiếp số lượng bản ghi N.

LINQ: dbContext.table.Where (w => w.id == 1) .Take (10);

sẽ tạo ra SQL sau

chọn top 10 * từ bảng

bạn sẽ nhìn thấy truy vấn genereted sử dụng SQL Server hồ sơ hoặc khi chạy trong trình gỡ lỗi, IntelliTrace cho thấy các truy vấn SQL thực hiện.

tôi hy vọng nó hữu ích.

2

Nó làm tốt nhất có thể.

Vì bạn dường như đang sử dụng SQL Server và công cụ của nó biết về SQL Server có một TOP, nó sẽ sử dụng nó. Nó cũng sẽ sử dụng nó với MS Access.

Nếu bạn đang sử dụng PostgreSQL, MySQL hoặc SQL Lite, nó sẽ sử dụng LIMIT.

Nó cũng có thể sử dụng "fetch first " + n + " rows only" (kiểu chuẩn DB2 và SQL: 2008) hoặc "select first " + n + "from" (kiểu Informix) hoặc "select * from (" + restOfQuery + ") where rownum <= " + n trên Oracle hoặc bất kỳ cơ sở dữ liệu nào cần thiết.

Và nếu ai đó đã viết một công cụ cho cơ sở dữ liệu hoàn toàn không thể hỗ trợ các giới hạn đó thì thực sự có thể đóng luồng kết quả sau khi đã thực hiện những gì cần thiết.

Dù bằng cách nào, cách tốt nhất có thể trong trường hợp cụ thể.

Nó cũng có, tình cờ, sử dụng phương pháp tương tự với một giá trị của 1 cho First() và các biến thể của nó và với một giá trị của 2 cho Single() và các biến thể của nó (vì bạn cần phải cố gắng để mất ít nhất 2 hàng để kiểm tra rằng có chỉ có 1 để lấy).

0

Đây là những gì tôi sử dụng mọi cho gridviews tôi phân trang với hiệu suất tuyệt vời:

resultList = context.MYTABLE.Where(WhereClause).OrderBy(orderCondition).Skip(firstItemIndex).Take(lastItemIndex - firstItemIndex + 1).ToList(); 
+1

Ngoài việc hiển thị mã, hãy nhớ giải thích lý do tại sao nó hoạt động. – SOFe

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