Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

LINQ to SQL Take без пропускане Причинява множество SQL изрази

Първо - някои аргументи за грешката Take.

Акопросто вземете , преводачът на заявки просто използва top. Топ10 няма да даде правилния отговор, ако мощността е нарушена чрез присъединяване към дъщерна колекция. Така че преводачът на заявки не се присъединява към дъщерната колекция (вместо това прави заявки за децата).

Ако пропуснете и вземете , след това преводачът на заявката се включва с някаква логика RowNumber над родителските редове... тези номера на редове позволяват да отнеме 10 родителя, дори ако това наистина са 50 записа, тъй като всеки родител има 5 деца.

Ако Пропуснете(0) и вземете , Skip се премахва като неизпълнение от преводача - това е точно както никога не сте казвали Skip.

Това ще бъде труден концептуален скок от мястото, където сте (извикване на Skip and Take) до „просто решение“. Това, което трябва да направим - е да принудим превода да се случи в точка, където преводачът не може да премахне Skip(0) като не-операция. Трябва да се обадим на Skip и да предоставим пропуснатия номер на по-късен етап.

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Групово вмъкване на SQL Server – част 1

  2. Динамично изпълнение на SQL в SQL Server

  3. Десетични стойности в SQL за разделяне на резултатите

  4. Вътрешни елементи за репликация на транзакции на SQL Server

  5. Поправете съобщение 241 „Преобразуването не бе успешно при преобразуване на дата и/или час от низ от знаци“ в SQL Server