2009-05-30 6 views
0

Est-ce que cela prend le nombre spécifié et s'arrête pendant l'interrogation ou après que toute la liste est déjà dans la collection? Quel est l'avantage de la performance, s'il y en a, lorsque vous «prenez»?Quand Linq's Take prend-il les résultats?

Répondre

3

Toutes les requêtes se produisent lors de l'énumération. Du point de vue de la performance, Take devrait être en mesure de déterminer le moyen le plus efficace de saisir un certain nombre d'éléments.

Cela signifie transférer dans une instruction "TOP n" dans Linq to SQL.

.

Mon Résultat (q.Take(10)).ToString():

SELECT TOP (10) [t0].[UserID], [t0].[RoleID] 
FROM [dbo].[UsersRoles] AS [t0] 

.

Et, le résultat de (q.Skip(10).Take(10)).ToString():

SELECT [t1].[UserID], [t1].[RoleID] 
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t0].[UserID], [t0].[RoleID]) AS [ROW_NUMBER], [t0].[UserID], [t0].[RoleID] 
    FROM [dbo].[UsersRoles] AS [t0] 
    ) AS [t1] 
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1 
ORDER BY [t1].[ROW_NUMBER] 
+0

si je fais 'Orderby' FIrst? – zsharp

+0

Toutes ces opérations sont différées vers SQL Server, ce qui permet d'utiliser des index, etc. pour obtenir les meilleures performances possibles. –

1

Vous n'obtiendrez le nombre d'enregistrements spécifiés retour de la base de données, le filtrage se fait dans le SQL.

+0

et si je fais 'Orderby' d'abord? – zsharp

+0

aucune différence. L'arbre d'expression se traduira par le même sql –

1

Les autres réponses étaient en rapport avec LINQ to SQL qui est aussi dans les balises mais il vaut la peine de mentionner que LINQ to Objects fera ce que vous avez suggéré. Effectivement faire quelque chose comme ceci:

int i = 0; 
foreach (var item in items) { 
    if (i++ < count) { 
     yield return item; 
    } 
} 

Donc en d'autres termes il prend seulement autant qu'il a besoin et s'arrête dès qu'il le peut.

Et évidemment une conséquence de cela signifie que:

var c = items.Take(10); // not yet enumerated 
c.Count(); // enumerated the first 10 
c.Count(); // enumerated the first 10 again 
Questions connexes