Đầu tiên - một số lý do cho lỗi Take.
Nếu bạn chỉ Lấy , trình dịch truy vấn chỉ sử dụng hàng đầu. Top10 sẽ không đưa ra câu trả lời đúng nếu cardinality bị phá vỡ bằng cách tham gia vào một tập hợp con. Vì vậy, trình dịch truy vấn không tham gia vào tập hợp con (thay vào đó nó truy vấn lại các tập hợp con).
Nếu bạn Bỏ qua và lấy , sau đó trình biên dịch truy vấn bắt đầu với một số logic RowNumber trên các hàng cha ... những con số này cho phép 10 bậc cha mẹ, ngay cả khi đó thực sự là 50 bản ghi do mỗi bậc cha mẹ có 5 con.
Nếu bạn Bỏ qua (0) và Lấy , Skip bị người dịch xóa vì không hoạt động - giống như bạn chưa bao giờ nói Skip.
Đây sẽ là một bước nhảy vọt về khái niệm khó từ vị trí của bạn (gọi Skip and Take) đến một "cách giải quyết đơn giản". Những gì chúng ta cần làm - là buộc quá trình dịch diễn ra tại một điểm mà người dịch không thể loại bỏ Skip (0) như một thao tác không hoạt động. Chúng tôi cần gọi Skip và cung cấp số đã bỏ qua sau đó.
DataClasses1DataContext myDC = new DataClasses1DataContext();
//setting up log so we can see what's going on
myDC.Log = Console.Out;
//hierarchical query - not important
var query = myDC.Options.Select(option => new{
ID = option.ParentID,
Others = myDC.Options.Select(option2 => new{
ID = option2.ParentID
})
});
//request translation of the query! Important!
var compQuery = System.Data.Linq.CompiledQuery
.Compile<DataClasses1DataContext, int, int, System.Collections.IEnumerable>
( (dc, skip, take) => query.Skip(skip).Take(take) );
//now run the query and specify that 0 rows are to be skipped.
compQuery.Invoke(myDC, 0, 10);
Điều này tạo ra truy vấn sau:
SELECT [t1].[ParentID], [t2].[ParentID] AS [ParentID2], (
SELECT COUNT(*)
FROM [dbo].[Option] AS [t3]
) AS [value]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ID]) AS [ROW_NUMBER], [t0].[ParentID]
FROM [dbo].[Option] AS [t0]
) AS [t1]
LEFT OUTER JOIN [dbo].[Option] AS [t2] ON 1=1
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p1 + @p2
ORDER BY [t1].[ROW_NUMBER], [t2].[ID]
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [0]
-- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [0]
-- @p2: Input Int (Size = 0; Prec = 0; Scale = 0) [10]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1
Và đây là nơi chúng tôi giành chiến thắng!
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p1 + @p2