189 votes

LINQ-to-SQL ou procédures stockées ?

J'ai jeté un coup d'œil à l'article "Beginner's Guide to LINQ" sur StackOverflow ( Guide pour débutants sur LINQ ), mais j'avais une question complémentaire :

Nous sommes sur le point de lancer un nouveau projet dans lequel presque toutes les opérations de la base de données seront des récupérations de données assez simples (un autre segment du projet écrit déjà les données). La plupart de nos autres projets jusqu'à présent utilisent des procédures stockées pour ce genre de choses. Cependant, j'aimerais tirer parti de LINQ-to-SQL si cela est plus logique.

Donc, la question est la suivante : Pour de simples récupérations de données, quelle est la meilleure approche, LINQ-to-SQL ou les procs stockés ? Des avantages ou des inconvénients spécifiques ?

Merci.

193voto

Chris Gillum Points 3782

Quelques avantages de LINQ par rapport aux sprocs :

  1. Sécurité de type : Je pense que nous comprenons tous cela.
  2. Abstraction : Ceci est particulièrement vrai pour LINQ-to-Entities . Cette abstraction permet également au framework d'ajouter des améliorations supplémentaires dont vous pouvez facilement tirer parti. PLINQ est un exemple de l'ajout du support multi-threading à LINQ. Les changements de code sont minimes pour ajouter ce support. Il serait BEAUCOUP plus difficile de faire ce code d'accès aux données qui appelle simplement des sprocs.
  3. Support de débogage : Je peux utiliser n'importe quel débogueur .NET pour déboguer les requêtes. Avec les sprocs, vous ne pouvez pas facilement déboguer le SQL et cette expérience est largement liée à votre fournisseur de base de données (MS SQL Server fournit un analyseur de requêtes, mais souvent cela ne suffit pas).
  4. Agnostique vis-à-vis des fournisseurs : LINQ fonctionne avec de nombreuses bases de données et le nombre de bases de données supportées ne fera qu'augmenter. Les sprocs ne sont pas toujours portables entre les bases de données, soit à cause de la syntaxe variable ou du support des fonctionnalités (si la base de données supporte les sprocs).
  5. Déploiement : D'autres l'ont déjà mentionné, mais il est plus facile de déployer un seul assemblage que de déployer un ensemble de sprocs. Ceci est également lié au point 4.
  6. Plus facile : Vous n'avez pas à apprendre T-SQL pour faire de l'accès aux données, ni à apprendre l'API d'accès aux données (par exemple ADO.NET) nécessaire pour appeler les sprocs. Ceci est lié aux points 3 et 4.

Quelques inconvénients de LINQ par rapport aux sprocs :

  1. Trafic réseau En effet, les sprocs n'ont besoin que de sérialiser le nom de la sproc et les données des arguments sur le fil alors que LINQ envoie la requête complète. Cela peut devenir très difficile si les requêtes sont très complexes. Cependant, l'abstraction de LINQ permet à Microsoft d'améliorer cet aspect au fil du temps.
  2. Moins flexible : Les Sprocs peuvent tirer pleinement parti des fonctionnalités d'une base de données. LINQ a tendance à être plus générique dans son support. Ceci est commun à tout type d'abstraction de langage (par exemple, C# contre assembleur).
  3. Recompilation de : Si vous devez apporter des modifications à la façon dont vous accédez aux données, vous devez recompiler, versionner et redéployer votre assemblage. Les Sprocs peuvent parfois permettent à un DBA de régler la routine d'accès aux données sans avoir à redéployer quoi que ce soit.

La sécurité et la facilité de gestion sont des sujets sur lesquels les gens se disputent également.

  1. Sécurité : Par exemple, vous pouvez protéger vos données sensibles en limitant l'accès aux tables directement, et mettre des ACL sur les sprocs. Avec LINQ, cependant, vous pouvez toujours restreindre l'accès direct aux tables et, à la place, mettre des ACL sur les tables actualisables vues pour atteindre un objectif similaire (en supposant que votre base de données supporte les vues actualisables).
  2. Gérabilité : L'utilisation de vues vous donne également l'avantage de protéger votre application de manière non cassante des changements de schéma (comme la normalisation des tables). Vous pouvez mettre à jour la vue sans que votre code d'accès aux données ne soit modifié.

J'avais l'habitude d'être un grand fan de sproc, mais je commence à pencher vers LINQ comme une meilleure alternative en général. S'il y a des domaines où les sprocs sont clairement meilleures, alors j'écrirai probablement encore une sproc mais j'y accéderai en utilisant LINQ. :)

34 votes

"LINQ fonctionne avec de nombreuses bases de données" Mais LINQTOSQL ne supporte que SQL Server.

7 votes

LINQ to Entities fonctionne avec Postgres et MySql en plus de MSSQL. Je ne suis pas sûr, mais j'ai cru lire qu'il existait quelque chose pour Oracle.

0 votes

devart dotConnect dispose d'un système Oracle, mais il est très bogué. De plus, je n'arrive pas à surmonter le déficit de performances qu'entraîne le fait de devoir sélectionner des données dans la base de données pour les mettre à jour (Attach() est également possible, mais c'est plutôt minable).

80voto

Eric Z Beard Points 18473

Je suis généralement partisan de tout mettre dans des procédures stockées, pour toutes les raisons que les administrateurs de bases de données nous rabâchent depuis des années. Dans le cas de Linq, il est vrai qu'il n'y aura pas de différence de performance avec de simples requêtes CRUD.

Mais gardez quelques éléments à l'esprit lorsque vous prenez cette décision : l'utilisation de tout ORM vous lie étroitement à votre modèle de données. Un DBA n'a aucune liberté pour apporter des modifications au modèle de données sans vous obliger à modifier votre code compilé. Avec les procédures stockées, vous pouvez masquer ces types de modifications dans une certaine mesure, puisque la liste des paramètres et le(s) ensemble(s) de résultats renvoyé(s) par une procédure représentent son contrat, et les entrailles peuvent être modifiées, à condition que ce contrat soit toujours respecté.

De plus, si Linq est utilisé pour des requêtes plus complexes, le réglage de la base de données devient une tâche beaucoup plus difficile. Lorsqu'une procédure stockée fonctionne lentement, le DBA peut se concentrer totalement sur le code de manière isolée, et dispose de nombreuses options, afin que le contrat soit toujours satisfait lorsqu'il a terminé.

J'ai vu de très nombreux cas où de graves problèmes dans une application ont été résolus par des modifications du schéma et du code dans les procédures stockées sans aucun changement dans le code déployé et compilé.

Peut-être qu'une approche hybird serait agréable avec Linq ? Linq peut, bien sûr, être utilisé pour appeler des procédures stockées.

0 votes

@Eric LINQ to ADO.NET Entities ne vous lie pas à un modèle de données. Avec le cadre d'entités, vous définissez un modèle de données conceptuel qui est mappé au modèle de stockage, que vous pouvez modifier à tout moment, même sans compiler (à condition que le mappage soit dans un fichier texte et non dans le binaire).

9 votes

Une caractéristique que vous avez négligée est la sécurité. Avec Linq, vous devez exposer les tables directement à l'application. Avec les procédures stockées, vous pouvez limiter l'accès à ces procédures et faire respecter vos exigences professionnelles.

1 votes

J'aime bien votre idée d'approche hybride : s'il s'agit d'un simple CRUD qui ne nécessite pas de jointures ni d'indices de verrouillage, surtout si vous n'interrogez qu'un seul champ, alors vous savez que le schéma ne va pas changer et vous n'aurez pas à vous battre avec le DBA.

64voto

Keith Points 46288

Linq to Sql.

Le serveur Sql mettra en cache les plans de requête, il n'y a donc pas de gain de performance pour les sprocs.

Vos instructions linq, en revanche, feront logiquement partie de votre application et seront testées avec elle. Les sprocs sont toujours un peu séparés et sont plus difficiles à maintenir et à tester.

Si je travaillais sur une nouvelle application à partir de zéro en ce moment, j'utiliserais uniquement Linq, sans sprocs.

9 votes

Je ne suis pas d'accord avec vos commentaires sur l'absence de gain pour les sprocs. J'ai profilé une série d'approches de l'accès au serveur SQL sur un système de production, et l'utilisation de Prepare + procs stockés a donné les meilleurs résultats. Même à travers plusieurs appels de la même logique. Vous avez peut-être raison sur une base de données à faible utilisation, cependant.

0 votes

Si vous êtes, et serez, le développeur de requêtes de base de données le plus compétent, utilisez ce qui vous est le plus familier. Contrairement au code procédural, vous ne pouvez pas dire "si cela donne la bonne réponse, envoyez-le".

0 votes

Je pense que LINQ to SQL peut provoquer des recompilations lorsque la taille d'un paramètre de type chaîne change.

40voto

lomaxx Points 32540

Pour la recherche de données de base, j'opterais sans hésiter pour Linq.

Depuis que je suis passé à Linq, j'ai trouvé les avantages suivants :

  1. Déboguer mon DAL n'a jamais été aussi facile.
  2. La sécurité en temps de compilation lorsque votre schéma change est inestimable.
  3. Le déploiement est plus facile car tout est compilé en DLL. Plus besoin de gérer des scripts de déploiement.
  4. Étant donné que Linq peut interroger tout ce qui implémente l'interface IQueryable, vous pourrez utiliser la même syntaxe pour interroger XML, des objets et toute autre source de données sans avoir à apprendre une nouvelle syntaxe.

2 votes

pour moi, la sécurité au moment de la compilation est essentielle !

0 votes

Pour le déploiement cependant, si vous êtes dans une équipe d'entreprise qui a un cycle de déploiement et qu'un bogue existe qui doit être sorti rapidement, votre déploiement de DLL à travers l'AQ, etc, est probablement plus strict que le chemin vers le déploiement d'une seule base de données script. Vos avantages semblent mieux représenter un scénario de petite équipe/projet.

3 votes

Le déploiement de scripts SQL qui n'ont pas besoin de passer par l'AQ n'est pas nécessairement une bonne chose ici.

27voto

SQLMenace Points 68670

LINQ va gonfler le cache des procédures

Si une application utilise LINQ to SQL et que les requêtes impliquent l'utilisation de chaînes de caractères dont la longueur peut être très variable, le cache des procédures du serveur SQL sera gonflé par une version de la requête pour chaque longueur de chaîne possible. Par exemple, considérons les requêtes très simples suivantes créées à partir de la table Person.AddressTypes de la base de données AdventureWorks2008 :

var p = 
    from n in x.AddressTypes 
    where n.Name == "Billing" 
    select n;

var p = 
    from n in x.AddressTypes 
    where n.Name == "Main Office" 
    select n;

Si ces deux requêtes sont exécutées, nous verrons deux entrées dans le cache des procédures du serveur SQL : Une liée avec un NVARCHAR(7), et l'autre avec un NVARCHAR(11). Imaginez maintenant qu'il y ait des centaines ou des milliers de chaînes d'entrée différentes, toutes de longueurs différentes. Le cache des procédures serait inutilement rempli de toutes sortes de plans différents pour la même requête.

Plus d'informations ici : https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363290

10 votes

Quel argument stupide - il suffit d'utiliser une variable et votre problème est résolu.

6 votes

@John, il ne serait pas utile d'utiliser une validation au lieu d'une chaîne littérale puisqu'à la fin vous envoyez une chaîne littérale à la base de données. Cela peut ressembler à une variable dans votre code, mais ce sera une chaîne dans le T-SQL généré qui sera envoyé à la base de données.

15 votes

SQLMenace : Selon la page que vous avez indiquée, le problème est résolu dans VS2010.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X