Po pierwsze - trochę powodów do błędu Take.
Jeśli po prostu weź , tłumacz zapytań używa tylko góry. Top10 nie udzieli prawidłowej odpowiedzi, jeśli kardynalność zostanie złamana przez dołączenie do kolekcji podrzędnej. Dlatego tłumacz zapytań nie dołącza do kolekcji podrzędnej (zamiast tego wysyła zapytania o dzieci).
Jeśli Pomiń i weź , wtedy tłumacz zapytań uruchamia logikę Numeru Wiersza nad wierszami nadrzędnymi... te numery wierszy pozwalają mu wziąć 10 rodziców, nawet jeśli to naprawdę 50 rekordów, ponieważ każdy rodzic ma 5 dzieci.
Jeśli Pomiń(0) i weźmiesz , Pomiń jest usuwany jako niewykonanie przez tłumacza — to tak, jakbyś nigdy nie powiedział Pomiń.
To będzie trudny koncepcyjny skok z miejsca, w którym się znajdujesz (nazywając Skip and Take) do „prostego obejścia”. To, co musimy zrobić - to wymusić tłumaczenie w punkcie, w którym tłumacz nie może usunąć Skip(0) jako nieoperacji. Musimy zadzwonić do Skip i podać pominięty numer później.
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);
Daje to następujące zapytanie:
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
I tu wygrywamy!
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p1 + @p2