Ik probeer je een kort antwoord te geven op je twijfel, als je de skip(n).take(m)
uitvoert methoden op linq (met SQL 2005 / 2008 als databaseserver) uw query gebruikt de Select ROW_NUMBER() Over ...
statement, met op de een of andere manier directe paging in de SQL-engine.
Om u een voorbeeld te geven, ik heb een db-tabel genaamd mtcity
en ik schreef de volgende vraag (werk ook met linq to entiteiten):
using (DataClasses1DataContext c = new DataClasses1DataContext())
{
var query = (from MtCity2 c1 in c.MtCity2s
select c1).Skip(3).Take(3);
//Doing something with the query.
}
De resulterende vraag zal zijn:
SELECT [t1].[CodCity],
[t1].[CodCountry],
[t1].[CodRegion],
[t1].[Name],
[t1].[Code]
FROM (
SELECT ROW_NUMBER() OVER (
ORDER BY [t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]) AS [ROW_NUMBER],
[t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]
FROM [dbo].[MtCity] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]
Dat is een venster met gegevenstoegang (best cool, trouwens, want vanaf het allereerste begin worden gegevens geretourneerd en toegang tot de tabel zolang aan de voorwaarden wordt voldaan). Dit zal erg lijken op:
With CityEntities As
(
Select ROW_NUMBER() Over (Order By CodCity) As Row,
CodCity //here is only accessed by the Index as CodCity is the primary
From dbo.mtcity
)
Select [t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]
From CityEntities c
Inner Join dbo.MtCity t0 on c.CodCity = t0.CodCity
Where c.Row Between @p0 + 1 AND @p0 + @p1
Order By c.Row Asc
Met de uitzondering dat deze tweede query sneller wordt uitgevoerd dan het linq-resultaat, omdat het uitsluitend de index gebruikt om het gegevenstoegangsvenster te maken; dit betekent dat, als je wat filtering nodig hebt, de filtering moet (of moet zijn) in de entiteitslijst (waar de rij is gemaakt) en dat er ook enkele indexen moeten worden gemaakt om de goede prestaties te behouden.
Wat is nu beter?
Als je een vrijwel solide workflow in je logica hebt, zal het implementeren van de juiste SQL-manier gecompliceerd zijn. In dat geval is LINQ de oplossing.
Als je dat deel van de logica rechtstreeks naar SQL kunt verlagen (in een opgeslagen procedure), zal het nog beter zijn omdat je de tweede query kunt implementeren die ik je heb laten zien (met behulp van indexen) en SQL het uitvoeringsplan van de query (verbetering van de prestaties).