sql >> Database >  >> RDS >> Sqlserver

LINQ to SQL Take w/o Skip Veroorzaakt meerdere SQL-statements

Eerst - enige redenering voor de Take-bug.

Als je gewoon neemt , gebruikt de zoekvertaler gewoon top. Top10 geeft niet het juiste antwoord als kardinaliteit wordt doorbroken door mee te doen aan een kindercollectie. Dus de zoekopdrachtvertaler neemt niet deel aan de onderliggende verzameling (in plaats daarvan vraagt ​​het om de kinderen).

Als u Overslaan en nemen , dan begint de query-vertaler met wat RowNumber-logica over de bovenliggende rijen... deze rijnummers laten 10 ouders toe, zelfs als dat echt 50 records zijn omdat elke ouder 5 kinderen heeft.

Als u Overslaan(0) en nemen , Skip is verwijderd als een niet-handeling door de vertaler - het is net alsof je Skip nooit hebt gezegd.

Dit wordt een moeilijke conceptuele sprong van waar je bent (door Skip and Take te bellen) naar een "eenvoudige oplossing". Wat we moeten doen - is de vertaling afdwingen op een punt waar de vertaler Skip(0) niet kan verwijderen als een niet-bewerking. We moeten Skip bellen en het overgeslagen nummer later doorgeven.

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

Dit levert de volgende vraag op:

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

En hier winnen we!

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


  1. Splits één kolomwaarde in meerdere kolomwaarden

  2. Gegevens herhaaldelijk van SQL Server naar Oracle verplaatsen

  3. Big data sneller laden

  4. Hoe te upgraden van MariaDB 10.4 naar MariaDB 10.5