sql >> Databáze >  >> RDS >> Sqlserver

LINQ to SQL Take bez přeskakování způsobuje více příkazů SQL

Za prvé – nějaké zdůvodnění chyby Take.

Pokud jen vezměte , překladač dotazů používá pouze top. Top 10 neposkytne správnou odpověď, pokud je mohutnost narušena zapojením se do dětské sbírky. Překladač dotazů se tedy nepřipojuje k podřízené kolekci (místo toho se dotazuje na podřízené položky).

Pokud Přeskočit a vzít , pak překladač dotazů spustí nějakou logiku RowNumber nad nadřazenými řádky... tato čísla řádků umožňují zabrat 10 rodičů, i když je to skutečně 50 záznamů, protože každý rodič má 5 dětí.

Pokud Přeskočit(0) a vzít , Přeskočit je odstraněno jako neprovedení operace – je to jako byste nikdy neřekli Přeskočit.

Toto bude tvrdý koncepční skok z místa, kde se nacházíte (volání Skip and Take) k „jednoduchému řešení“. Co musíme udělat - je vynutit, aby se překlad uskutečnil v bodě, kde překladatel nemůže odstranit Skip(0) jako neoperaci. Musíme zavolat Skipovi a přeskočené číslo dodat později.

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);

To vytvoří následující dotaz:

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

A tady jsme vyhráli!

WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p1 + @p2


  1. Špatné návyky:Počítání řádků obtížným způsobem

  2. SQLite3.Exception:Obraz disku databáze je chybný

  3. Získejte aktuální hodnotu AUTO_INCREMENT pro libovolnou tabulku

  4. Sloučení/kombinace více souborů PDF do jednoho PDF v Oracle pomocí balíčku PLPDF_TOOLKIT PL/SQL