Donc, je me développe avec une entité + Linq pour un peu maintenant et je commence vraiment à m'interroger sur les meilleures pratiques. Je suis habitué au modèle de "si je dois obtenir des données, référencez une procédure stockée". Les procédures stockées peuvent être modifiées à la volée si nécessaire et ne nécessitent pas de recompilation de code. Je trouve que mes requêtes dans mon code ressemblent à ceci:
List<int> intList = SomeMgrThatDoesSQLExecute.GetResults( string.Format("SELECT [ID] FROM DBTable WHERE ForeignKeyId = {0}", fkIdToSearchFor));
5 Réponses :
La puissance de Linq ne se rend pas vraiment apparente tant que vous n'avez pas besoin de requêtes plus complexes.
Dans votre exemple, pensez à ce que vous auriez besoin de faire si vous souhaitez appliquer un filtre d'une forme de forme à votre requête. Utilisation de la chaîne construite SQL, vous devez ajouter des valeurs dans un constructeur de chaînes, protégé contre l'injection SQL (ou passer à travers les efforts supplémentaires de la préparation de paramètres par des paramètres). P>
Disons que vous vouliez ajouter une déclaration à votre requête LINQ; p> vous pouvez le prendre et le faire; p> Le SQL résultant ressemblerait; P> SELECT * FROM Table WHERE ForeignKeyId = fldToSearchFor AND Value > 5
Vous faites un bon point mais cela me permet de me demander si la facilité d'utilisation est plus importante que des requêtes polyvalentes. Est-il plus important d'avoir la commodité des requêtes LINQ au prix de leur codé dur dans votre application, de forcer les mises à jour lorsque ces requêtes changent même légèrement?
J'ai créé des référentiels qui renvoient toujours Select * à partir de la table. J'applique une couche de «droits d'accès» de ma demande entre cela et le développement normal, car je souhaite prendre le fardeau du développement. En utilisant cette méthode, je fournis toujours le développeur la capacité de manipuler la requête en outre, en ajoutant leurs propres filtres.
Oui, si vous êtes bon chez SQL, vous pouvez obtenir tout cela avec les PROC stockés et bénéficier de meilleures performances et des prestations de maintenance. p>
D'autre part, Linq est en sécurité, légèrement plus facile à utiliser (comme les développeurs sont habitués à partir de scénarios non-dB) et peuvent être utilisés avec différents fournisseurs (il peut se traduire par un code spécifique au fournisseur). Tout ce qui implémente En outre, vous pouvez transmettre des requêtes partiellement construites autour, et ils seront paresseux évalués uniquement en cas de besoin. P>
Alors, oui, vous sont forts> les codés dur, mais, essentiellement, c'est la logique de votre programme, et c'est durement codé comme une autre partie de votre code source. P> iquelérable code> peut être utilisé de la même manière avec Linq. P>
J'évite personnellement aux demandes SQL de code dur (comme votre deuxième exemple). Écrire Linq au lieu de la SQL réelle permet: p>
Si je dois obtenir des données, référez une procédure stockée. Procédures stockées peut être changé à la volée si nécessaire et ne nécessite pas de recompilation de code p> blockQuote>
-> Si vous devez mettre à jour votre modèle, vous devrez probablement également mettre à jour votre code pour prendre en compte la mise à jour de la DB. Donc, je ne pense pas que cela vous aidera à éviter une recompilation la plupart du temps. P>
Ok, j'écris cela, c'est bien que quelqu'un l'a fait.
est linq codant de manière difficile toutes vos questions dans votre application? Oui, absolument. P>
Examinons ce que cela signifie à votre application. p>
Si vous souhaitez modifier la manière dont vous obtenez des données, vous devez modifier votre code compilé; Vous ne pouvez pas créer un "hotfix" à votre base de données. P>
Mais, si vous changez une requête en raison d'une modification de votre modèle de données, vous allez probablement devoir changer votre modèle de domaine pour accueillir le changement. P>
Supposons que votre modèle n'a pas changé et que votre requête change, car vous devez fournir plus d'informations à la requête pour obtenir le bon résultat. Ce type de changement nécessite très certainement de modifier votre application pour permettre l'utilisation du nouveau paramètre d'ajouter un filtrage supplémentaire à la requête. P>
Encore une fois, supposons que vous êtes heureux d'utiliser une valeur par défaut pour le nouveau paramètre et que l'application n'a pas besoin de la spécifier. La requête pourrait inclure un champ dans le résultat. Vous n'avez pas à consommer ce champ supplémentaire et vous pouvez ignorer les informations supplémentaires envoyées sur le fil. Il a introduit un problème d'entretien ici, en ce que votre SQL est hors de pas avec l'interprétation de votre application. P>
dans ce scénario spécifique em> où vous ne faites pas une modification extérieure à la requête, ou votre application ignore les modifications, vous permettez de déployer votre changement de SQL uniquement sans avoir à Touchez l'application ou faites-la tomber pendant n'importe quel temps (ou si vous êtes dans des ordinateurs de bureau, déployez une nouvelle version). P>
de manière réaliste, lorsqu'il s'agit de modifier un système, Le seul STRAND> REAL STRAND> d'utiliser des procédures stockées sur LINQ est si vous souhaitez partager votre base de données entre plusieurs systèmes à l'aide d'une API cohérente sur la couche SQL. C'est une situation assez horrible et je préférerais développer une couche de service au-dessus de la base de données SQL pour vous éloigner de cette conception. P>
Je suis d'accord avec vos sentiments. Cependant, il est à dire que quelque chose pour avoir une base de données auto consistante pouvant être accessible directement sans aucun risque de véritable incohérence. (C'est-à-dire des contraintes ou des déclencheurs en appliquant toutes les règles de consistance fondées sur les données.) Ceci est parce que la base de données peut survivre à la couche de service originale qui l'utilisait. Je ne recommande pas d'accéder directement à la base de données si une couche de service exixte, mais idéalement, ne devrait pas être dangereuse.
Je ne discuterais pas que des contraintes (et dans une moindre mesure, des déclencheurs) sont des outils que vous devriez jeter. Ils sont un élément essentiel de l'intégrité des données et l'intégrité des données est la responsabilité fondamentale de la base de données.
Bon. Beaucoup de personnes qui utilisent des ormes aiment simplement conserver l'intégrité dans le code. Lorsqu'il n'utilise pas une couche de service partagée qui est distasserne, mais lorsque vous en utilisez un, vous pouvez souvent vous en tirer. Si je vous comprends correctement: vous acceptez que la DANGNEDSE est reportée pour le stockage et l'intégrationtrie et si l'on désire une API commune à la base de données pour plusieurs applications, une couche de service est préférable à des milliers de procédures stockées. Cela a du mal à moi.
Je me suis demandé aussi à ce sujet, mais la mentalité que l'interactivité est la base de données que dans la base de données niveau em> est un concept dépassé strong>. Avoir un DBA dédié Synchroniser des procédures stockées, tandis que plusieurs développeurs frontaux Les magasins Java sont titulaires de ce paradigme car ils n'ont pas d'outil tel que LINQ et détiennent ce paradigme en raison de la nécessité. Bases de données avec .Net trouvent que la nécessité d'une personne de base de données est lessoned si pas complètement supprimé, car une fois que la structure est en place les données peuvent être réglante em> strong> plus efficacement (comme le montre tous les autres intervenants de cet article) dans la couche de données utilisant LINQ que par RAW SQL. P>
Si on a une chance d'utiliser code d'abord et créer une base de données modèle em> à partir de la masse en provenant d'abord les classes d'entité d'abord dans le code, puis exécutant ef pour faire la magie de la création de la Base de données ... On comprend comment la base de données est vraiment un outil qui stocke des données et la nécessité de procédures stockées et d'un DBA dédié n'est pas nécessaire. P>
D'après mon expérience, la base de données dans tout système considérable est généralement le goulot d'étranglement de la performance et il est donc essentiel de garantir que les requêtes sont performantes et réglées de manière appropriée. Ce qui signifie que quelqu'un qui est orienté sur la base de données est crucial si vous voulez échouer. Ma préoccupation est toujours, que si la DB est traitée comme un citoyen de la 2e classe, alors tôt ou tard, il vous mordra mal quand cela fonctionne mal.
@AdatheDev ( J'ai fait des ADA dans les années 80 i>). Je suis tout à fait d'accord avec toi. Toute technologie peut rapidement aller dans les mauvaises herbes. Tout comme le paradigme de code de la machine où un programme dans une langue avancée qui crée le code de la machine, il ne sera pas aussi rapide que le code de montage modifié. Mais le compromis est là pour le temps pour compléter la vitesse des versets; Même conteste lorsque vous utilisez LINQ.
Oui, je ne peux pas discuter là-bas - cela améliore certainement la productivité afin que je puisse voir des avantages là-bas. Bien que la trouvant qu'il se confit avec ma base de données intérieure-geek!
La deuxième requête n'est pas une procédure stockée code>. La procédure stockée sera écrite à l'intérieur de votre base de données et le code d'entité n'appellera-t-il pas .Instead d'écriture
Sélectionnez l'instruction CODE> Écrire le nom de la procédure stockée
Je suis conscient que ce n'est pas une procédure stockée. J'essaie de souligner que si je fais une requête Linq contre un contexte d'entité, il a exactement la même chose que si je viens de codé dur la requête SQL dans le code.
Toujours demandé à ce sujet. Serait intéressé à voir la réponse!
Venant d'un fond orienté db, où j'ai toujours utilisé Ado.net directement pour la performance sans linq à SQL / EF Middle-Hommes, j'ai aussi des préoccupations similaires dans ces lignes.
En outre, la deuxième exemple de requête est sujette à l'injection SQL.