Во-первых - некоторые причины для ошибки Take.
Если вы просто возьмете , переводчик запросов просто использует top. Top10 не даст правильного ответа, если кардинальность будет нарушена при присоединении к детской коллекции. Таким образом, переводчик запросов не включается в дочернюю коллекцию (вместо этого он запрашивает дочерние элементы).
Если вы Пропустите и возьмите , тогда переводчик запросов включит некоторую логику RowNumber над родительскими строками ... эти числовые числа позволяют ему взять 10 родителей, даже если это действительно 50 записей из-за каждого родителя имея 5 детей.
Если вы Пропустите (0) и возьмете , Пропуск удален переводчиком как неоперация - это как если бы вы никогда не сказали Пропустить.
Это будет сложный концептуальный скачок от того места, где вы находитесь (вызывая Skip and Take) к «простому обходному пути». Что нам нужно сделать - это заставить перевод произойти в тот момент, когда переводчик не может удалить Skip (0) как неоперацию. Нам нужно позвонить в «Пропустить» и предоставить пропущенный номер позже.
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);
Создает следующий запрос:
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
И вот где мы победим!
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p1 + @p2