2010-01-11 5 views
2

En cherchant comment effectuer un SELECT TOP 5 avec LINQ-to-SQL, toutes les réponses que j'ai vues suggèrent d'utiliser .Take(), comme si:Performances LINQ to SQL avec les requêtes "SELECT TOP {x}"

var myObject = (
from myObjects in repository.GetAllMyObjects() 
select myObject) 
.Take(10); 

Je ne comprends pas encore plus de la façon dont fonctionne LINQ derrière les coulisses, mais à ma connaissance des langues C-comme cela résoudrait en attribuant d'abord un tableau temporaire contenant tous les enregistrements, puis copier le 10 premiers éléments dans le tableau à var. Ce n'est pas un problème si vous travaillez sur un petit jeu de données ou sans contraintes de performances, mais cela me semble terriblement inefficace si vous sélectionnez, par exemple, les 5 entrées les plus récentes d'une table pouvant contenir des millions d'enregistrements.

Est-ce que je comprends comment cela fonctionne mal? Si oui, quelqu'un pourrait-il expliquer ce qui se passe réellement? Sinon, quel (le cas échéant) est le meilleur (c'est-à-dire plus efficace) de sélectionner uniquement des enregistrements x via LINQ-to-SQL?

[modifier]

J'ai la classe myObject hypothétique sortie envoi LINQ to SQL à la sortie de débogage selon la suggestion contenue dans la réponse acceptée. J'ai fini par utiliser le DebuggerWriter à partir d'ici: http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11

+2

Dans votre débogueur, vous pouvez inspecter l'objet Linq et il vous montrera la requête SQL qu'il va exécuter. Peut-être que cela va aider? –

Répondre

3

Votre hypothèse est incorrecte. Avec Linq to SQL, il évalue à un Expression<Func<...>> qui peut être évalué et le bon SQL généré. Vous n'avez pas besoin de vous soucier de charger tous les enregistrements.

Voir aussi la question suivante. Vous pouvez attacher un flux à votre DataContext et voir le SQL généré. How to get the TSQL Query from LINQ DataContext.SubmitChanges()

+0

La consignation de sortie de contexte de données est une astuce géniale! – nathanchere

1

LINQ utilise une exécution différée et, pour LINQ-to-SQL, des arborescences d'expression.

Aucune requête ne sera exécutée jusqu'à ce que vous énumériez le résultat de l'appel Take, vous n'avez donc pas à vous soucier de quoi que ce soit.

1

Je viens juste de passer la dernière semaine! J'ai ouvert le profileur SQL sur ma base de données de développement et j'ai parcouru le code. C'était très intéressant de voir le SQL généré pour les différentes requêtes. Je recommande que vous fassiez de même. Ce n'est peut-être pas une réponse exacte à votre question, mais il était certainement éclairant de voir comment vos différents composants génèrent des instructions SQL entièrement différentes en fonction du contenu de l'appel. Je crois que la "résolution de requête différée" ou quelque chose (?) Lecture sur MSDN serait également éclairante.

+2

J'utilise une base de données SQL Express donc, autant que je sache, aucun profileur SQL pour moi dans cette instance :( – nathanchere