Zuerst - einige Gründe für den Take Bug.
Wenn Sie nur nehmen, verwendet der Abfrage-Übersetzer nur oben. Top10 wird nicht die richtige Antwort geben, wenn die Kardinalität durch die Teilnahme an einer Kindersammlung unterbrochen wird. Daher fügt der Abfrageübersetzer die untergeordnete Auflistung nicht hinzu (stattdessen werden die untergeordneten Elemente erneut abgefragt).
Wenn Sie überspringen und nehmen, dann die Abfrage Übersetzer beginnt mit einiger RowNumber Logik über die Eltern Reihen in ... diese rownumbers lassen Sie es 10 Eltern nehmen, auch wenn das wirklich 50 Datensätze aufgrund jeden Elternteil mit 5 Kindern .
Wenn Sie überspringen (0) und nehmen, Skip wird als eine Nicht-Operation durch den Übersetzer entfernt - es ist nur, wie Sie nie Skip gesagt haben.
Dies wird ein schwieriger konzeptioneller Sprung von wo Sie sind (Aufruf von Skip and Take) zu einer "einfachen Problemumgehung". Was wir tun müssen - ist, dass die Übersetzung an einem Punkt erzwungen wird, an dem der Übersetzer Skip (0) nicht als Nicht-Operation entfernen kann. Wir müssen Skip aufrufen und die übersprungene Nummer zu einem späteren Zeitpunkt angeben.
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);
Daraus ergibt sich die folgende Abfrage:
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
Und hier, wo wir gewinnen!
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p1 + @p2
Das funktioniert, aber ich musste IEnumerable statt nur IEnumerable verwenden, um ToList aufrufen. Es ist auch eine halbe Sekunde schneller in meinem Testfall. Gute Antwort. –
JohnOpincar