Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

LINQ to SQL Take bez pomijania powoduje wiele instrukcji SQL

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Użyj CRYPT_GEN_RANDOM(), aby utworzyć kryptograficzną, losową liczbę w SQL Server

  2. MSDTC na serwerze „serwer jest niedostępny”

  3. Jakie są różnice między indeksem klastrowym a nieklastrowym?

  4. Zbiorczy import SQL z CSV

  5. skuteczny sposób na wdrożenie stronicowania