sql >> Databasteknik >  >> RDS >> Sqlserver

LINQ till SQL Take w/o Skip Orsakar flera SQL-satser

Först - lite resonemang för Take-buggen.

Om du bara tar , frågeöversättaren använder bara top. Top10 kommer inte att ge rätt svar om kardinalitet bryts genom att gå med i en barnsamling. Så frågeöversättaren går inte med i barnsamlingen (istället efterfrågar den för barnen).

Om du Hoppa över och ta , sedan startar frågeöversättaren med lite RowNumber-logik över föräldraraderna... dessa radnummer låter det ta 10 föräldrar, även om det egentligen är 50 poster på grund av att varje förälder har 5 barn.

Om du Hoppa över(0) och ta , Skip tas bort som en icke-operation av översättaren - det är precis som du aldrig sa Hoppa över.

Det här kommer att bli ett svårt konceptuellt språng dit du befinner dig (som ringer Skip and Take) till en "enkel lösning". Vad vi behöver göra - är att tvinga översättningen att ske vid en punkt där översättaren inte kan ta bort Skip(0) som en icke-operation. Vi måste ringa Skip och ange det överhoppade numret vid ett senare tillfälle.

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

Detta ger följande fråga:

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

Och det är här vi vinner!

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


  1. Migrera en Oracle-databas från AWS EC2 till AWS RDS, del 2

  2. Hur man kontrollerar om SQL-databasen är skadad - Lösning för att reparera MDF-fil

  3. Exempel på JDBC-uttalande – Infoga, Ta bort, Uppdatera, Välj post

  4. Hur man uppdaterar tabellen i oracle