Je suis nouveau sur ef et je l'aime car il réduit les frais d'écriture des requêtes courantes en le remplaçant par de simples fonctions d'ajout et de suppression. D'accord.
Aujourd'hui, je me suis disputé avec mon collègue qui l'utilise depuis un certain temps et je l'ai approché pour savoir quand utiliser les procédures stockées et quand utiliser EF et pour quoi faire?
Il a répondu;
Regardez, la chose simple est que vous pouvez utiliser les deux, mais quel est l'intérêt d'utiliser un ORM si vous faites tout cela dans une base de données, c'est-à-dire des procédures stockées. Alors, comment sauriez-vous quoi faire où et pourquoi? Une formule simple que j'ai apprise qui utilise ORM pour toutes les opérations CRUD et les requêtes qui nécessitent 3-4 jointures, mais quoi que ce soit au-delà, il vaut mieux utiliser des procédures stockées.
J'ai pensé, analysé et répondu;
Eh bien, ce n'est pas le cas, j'ai vu des blogs et des exemples où les gens font des choses énormes avec EF et n'ont pas eu besoin d'écrire de procédure.
Mais il est têtu et appelle cela des frais généraux de performance qui sont encore au-delà de ma compréhension puisque je suis relativement nouveau par rapport à lui.
Donc, ma question est de savoir si vous avez seulement besoin de gérer CRUD en ef ou si vous devez en faire beaucoup plus en EF en remplacement des procédures stockées.
J'ai tendance à adopter votre approche en la matière. Les ORM sont parfaits pour les CRUD de base et les requêtes relativement simples, mais souvent je préfère aller directement à la base de données, généralement pour des raisons de performances.
Je peux écrire une vue complexe (ou sproc) dans SQL Server qui peut être optimisée beaucoup plus facilement que la même chose dans Linq. D'un autre côté, je pense qu'il est également correct de se méfier de mettre une logique réelle dans votre base de données.
Les ORM sont un outil pour interagir avec une base de données, et pour les choses quotidiennes, ils peuvent simplifier énormément au lieu d'écrire des instructions SQL. Mais, comme c'est le cas avec à peu près tous les autres outils, ce n'est pas une solution miracle pour remplacer complètement l'interaction DB.
J'ai tendance à suivre deux règles:
dbo.GenerateReportSet
, Par exemple, pourrait être appelé comme _context.GenerateReportSet(dateStart, dateEnd)
Mais il est têtu et appelle cela des frais généraux de performance qui échappent encore à ma compréhension
Il est difficile d'avoir une discussion détaillée sur quelque chose lorsque vous ne comprenez pas (et ne pouvez donc pas reconnaître) une partie du problème au départ.
Très simplement: l'automatisation ne peut être que si intelligente. Lorsqu'il s'agit de requêtes complexes et complexes, EF génère une requête de travail, mais elle ne sera pas aussi efficace que vous le souhaitez.
EF n'est pas mal développé. Les requêtes inefficaces générées ne sont qu'une conséquence inévitable de ce que EF est (et n'est pas) conçu pour faire. EF est un excellent outil qui évite le code trivial et répétitif; mais ces avantages sont perdus lorsque vous traitez des requêtes hautement personnalisées (généralement complexes).
Pensez-y de cette façon: ma berline est conçue pour une utilisation sur route. Sur la route, il sera beaucoup plus facile à conduire qu'un gros 4x4. Puis-je emmener ma voiture hors route? Dans des limites raisonnables, oui. Mais ma voiture n'a pas été conçue pour le tout-terrain, et donc les avantages de ma voiture sont perdus lorsqu'elle n'est pas sur la route, tandis que le 4x4 commence à briller et sera plus facile à conduire hors route.
Comme ma voiture est conçue pour une utilisation sur route, EF est conçu pour des tâches CRUD simples. Il peut être utilisé d'autres façons, mais personne ne l'a conçu dans cet esprit.
"Regardez, la chose simple est que vous pouvez utiliser les deux, mais quel est l'intérêt d'utiliser un ORM si vous faites tout cela dans une base de données, c'est-à-dire des procédures stockées."
Cet argument n'a guère de sens. Quel est l'intérêt d'utiliser une brosse à dents si votre bras déplace la brosse à dents de toute façon. Utilisez simplement votre bras pour nettoyer vos dents!
Eh bien, ce n'est pas le cas, j'ai vu des blogs et des exemples où les gens font des choses énormes avec EF et n'ont pas eu besoin d'écrire de procédure.
Ce n'est pas parce que cela peut être fait que cela se fait bien. J'ai vu des gens manger la nourriture que je préparais, mais cela ne veut pas dire que je suis un bon cuisinier. Cela signifie simplement que je ne suis pas totalement incapable de cuisiner.
EF peut faire beaucoup de choses, mais son efficacité commence à s'effondrer à mesure que la complexité de la requête augmente. Dans les cas où l'atteinte de performances suivante est inacceptable, EF n'est pas l'outil à utiliser.
Donc, ma question est de savoir si vous avez seulement besoin de gérer CRUD en ef ou si vous devez en faire beaucoup plus en EF en remplacement des procédures stockées.
Comme beaucoup de choses, cela dépend de ce dont vous avez besoin.
Pour les opérations CRUD simples, EF est un bon outil à utiliser. Il supprime le besoin de beaucoup de logique de manipulation standardisée.
Si vous n'avez que des requêtes de données simples ou si vous ne vous souciez pas d'optimiser les performances, vous pouvez utiliser EF pour celles-ci car vous utilisez déjà EF pour CRUD de toute façon.
Cependant, si vous avez des requêtes de données complexes et que vous vous souciez de l'optimisation des performances, vous ne voudrez pas utiliser EF. Notre architecte principal (qui était auparavant un DBA et se soucie beaucoup des performances de la base de données) préconise actuellement d'utiliser EF et Dapper simultanément, en particulier parce qu'ils se spécialisent chacun dans une partie de la charge de travail. Il a initialement suggéré d'utiliser uniquement Dapper, mais il a concédé la facilité de CRUD avec EF et accepte son utilisation dans les applications lourdes CRUD.
Mais là encore, c'est subjectif. Vous préférerez peut-être vous en tenir à un seul outil et éliminer les inconvénients (par exemple, utiliser EF et traiter des requêtes complexes et lentes; ou utiliser Dapper et éviter d'avoir à écrire du code CRUD standard). Ou vous pouvez être en faveur de l'utilisation de différents outils pour pouvoir à tout moment réduire les performances.
Comme toujours, cela dépend. Les procédures stockées, les vues, les index et les déclencheurs (etc.) sont d'excellents outils pour un DBA, s'assurant que la base de données (relationnelle) elle-même garantit la cohérence, sécurise les autorisations appropriées et fonctionne aussi bien que possible.
Cependant, ces outils sont un chemin sûr vers une conception centrée sur la base de données, où tout le système tourne autour de la base de données. Cela signifie que tout le code devra s'adapter au modèle de base de données physique. Les types de données utilisés par la base de données dicteront les types en mémoire, etc. La raison en est qu'il sera très difficile d'initier une refactorisation de la couche de base de données à partir de votre code logique métier si une recactorisation comprend la réécriture (et le test/débogage) procédures stockées, déclencheurs et code SQL personnalisé.
Le principal avantage des EF (et des outils similaires) n'est pas (à mon humble avis) qu'ils rendent les composants CRUD simples faciles à développer, mais que le refactoring ultérieur de ces composants devient beaucoup plus facile. (Étant donné que vous faites d'abord du code)
Oui, il y a un prix à payer une fois que vous commencez à effectuer des jointures complexes. Ce prix est beaucoup plus élevé si vous avez une approche naïve d'EF.
Cependant
Si vous rencontrez des problèmes de performances réels (comme l'utilisateur final en souffre) en raison de requêtes SQL contenant des jointures complexes, les procédures stockées sont au mieux un pansement.
Vous pouvez optimiser le stockage pour l'intégrité des données ou pour les performances des requêtes, mais pas les deux. Si vous avez besoin des deux, examinez le CQRS ou les modèles similaires.
TL; DR
Juste pour ajouter à ce que @Guran a répondu: je n'ai pas d'expérience avec EF en particulier, mais j'ai vu qu'il est facile d'oublier que vous avez affaire à des jointures et à des opérations coûteuses lorsque vous utilisez un ORM. Vous commencez donc à traiter les instances de modèle comme des variables régulières et à les inclure dans des opérations complexes qui à leur tour seront probablement transformées en requêtes SQL encore plus complexes. J'ai également vu du code côté client avec des boucles et des agrégations qui auraient pu être faites plus efficacement dans le serveur de base de données.
Donc, si vous écrivez à la main des procédures sql/stores, vous serez plus conscients des implications en termes de performances.
Dans la plupart des cas où un sproc est nécessaire pour certaines exigences. Placez un fichier de script sql dans la base de code à exécuter dans le cas de futurs besoins de refactorisation de règles métier. Je suppose que la plupart des développeurs nouveaux et expérimentés ont une certaine expérience de travail dans un dbms. Toute personne ayant besoin de connaître les exigences de DB sproc peut consulter et mettre à jour les scripts selon les besoins. Les règles métier et les exigences de base de données existent dans les fichiers de code source. Je crois qu'il n'y a pas de méthode à sens unique dans la plupart des solutions complexes. (JMO).