Je travaille avec une base de données SQL Server avec plus de 1000 tables, quelques centaines de vues et plusieurs milliers de procédures stockées. Nous envisageons de commencer à utiliser Entity Framework pour nos nouveaux projets et nous travaillons à notre stratégie pour le faire. Ce que je raccroche, c’est la meilleure façon de scinder les tables en différents modèles (EDMX ou DbContext si l’on passe au code en premier). Je peux penser dès le départ à quelques stratégies:
- Divisé par schéma
Nous avons nos tables divisées en probablement une douzaine de schémas. Nous pourrions faire un modèle par schéma. Ce n'est pas parfait, cependant, car dbo finit toujours par être très volumineux, avec plus de 500 tables / vues. Un autre problème est que certaines unités de travail finiront par effectuer des transactions couvrant plusieurs modèles, ce qui ajoute à la complexité, bien que je suppose que EF rend cela assez simple. - Diviser par intention
Au lieu de se préoccuper des schémas, divisez les modèles par intention. Nous aurons donc différents modèles pour chaque application, projet, module ou écran, en fonction de la granularité souhaitée. Le problème que je vois avec ceci est que certaines tables doivent inévitablement être utilisées dans tous les cas, telles que User ou AuditHistory. Est-ce que nous les ajoutons à chaque modèle (viole DRY je pense), ou sont-ils dans un modèle séparé utilisé par chaque projet? - Ne divisez pas du tout - un modèle géant
Ceci est évidemment simple du point de vue du développement, mais d'après mes recherches et mon intuition, il semble que les performances puissent être terribles, à la fois au moment de la conception, de la compilation et éventuellement de l'exécution.
Quelle est la meilleure pratique pour utiliser EF avec une base de données aussi volumineuse? Quelles stratégies utilise-t-on spécifiquement dans la conception de modèles pour ce volume d’objets de base de données? Y a-t-il des options pour lesquelles je ne pense pas que cela fonctionne mieux que ce que j'ai ci-dessus?
En outre, est-ce un problème dans d'autres ORM tels que NHibernate? Si oui, ont-ils trouvé de meilleures solutions que EF?
la source
Réponses:
Personnellement, j'ai essayé de créer un schéma énorme pour toutes mes entités sur un projet assez complexe mais de petite taille (~ 300 tables). Nous avions une base de données extrêmement normalisée (normalisation de 5ème forme (je le dis vaguement)) avec beaucoup de relations "plusieurs à plusieurs" et une application extrême de l'intégrité référentielle.
Nous avons également utilisé une stratégie "d'instance unique par demande", ce que je ne suis pas convaincu non plus d'avoir aidé.
Lors de la création de listes "définies explicitement" simples et raisonnablement plates, la recherche et l’enregistrement des performances étaient généralement acceptables. Mais lorsque nous avons commencé à creuser des relations profondes, la performance semblait prendre des creux drastiques. Comparé à un proc stocké dans ce cas, il n'y avait aucune comparaison (bien sûr). Je suis sûr que nous aurions pu peaufiner la base de code ici et là pour améliorer les performances. Cependant, dans ce cas, nous avions simplement besoin d'optimiser les performances sans analyse en raison de contraintes de temps, et nous sommes revenus au processus stocké (toujours cartographié). via EF, parce que EF fournissait des résultats fortement typés), nous n’avions besoin de cela que pour nous replier dans quelques zones. Lorsque nous avons dû parcourir la base de données pour créer une collection (en utilisant .include () sans ménagement), la performance était sensiblement dégradante, mais nous en demandions peut-être trop.
Donc, sur la base de mon expérience, je recommanderais de créer un fichier .edmx distinct par intention. Générez uniquement ce que vous utiliserez en fonction de l'ampleur de ce besoin. Vous pouvez avoir des fichiers .edmx de taille réduite pour des tâches spécifiques, puis des fichiers volumineux dans lesquels vous devez traverser des relations complexes pour créer des objets. Je ne sais pas où se trouve cet endroit magique, mais je suis sûr qu'il y en a un ... lol ...
Honnêtement cependant, mis à part quelques pièges que nous avons en quelque sorte vus à venir (complexe traversant), l’immense .edmx a bien fonctionné du point de vue du "travail". Mais vous devrez faire attention à la magie de "réparation" que le contexte fait derrière la scène si vous ne le désactivez pas explicitement. En plus de synchroniser le .edmx lorsque des modifications sont apportées à la base de données, il était parfois plus facile d’effacer toute la surface et de recréer les entités, ce qui prenait environ 3 minutes, donc ce n’était pas si grave.
C'était tout avec EntityFramework 4.1. J'aimerais aussi connaître votre choix final et votre expérience.
Et en ce qui concerne votre question sur nHibernate, c’est une question de canette de ver à mon avis, vous allez aboyer des deux côtés de la barrière ... j’entends beaucoup de gens dénigrer EF pour pouvoir dénigrer sans travailler à travers le défis et compréhension des nuances propres à EF lui-même .. et bien que je n’aie jamais utilisé nHibernate en production, en général, si vous devez créer manuellement et explicitement des éléments tels que des mappages, vous obtiendrez un contrôle plus fin. peut glisser-déposer, générer et commencer à créer des requêtes et des requêtes en utilisant LINQ, je pourrais vous donner une merde sur la granularité.
J'espère que ça aide.
la source
Permettez-moi de commencer par une simple clarification: je n’ai pas d’expérience avec une base de données aussi volumineuse, le reste de ma réponse n’est donc pas basé sur l’exemple du monde réel.
Vous avez donc une base de données BIG et vous souhaitez l’utiliser avec ORM / EF. J'irais avec le deuxième choix. Voici ma simple explication pourquoi:
la source
Je dirais que vous ne pouvez pas décider de ce genre de question d'un point de vue technique. Je vous recommanderais de construire votre architecture en fonction de vos cas d'utilisation (user stories, etc.). Commencez par trouver vos objets métier. Un objet entité n'est pas par défaut un objet métier. En règle générale, vous aurez un objet métier devant les objets entité. Vous pouvez ensuite décider progressivement de ce dont vous avez réellement besoin, en fonction des besoins de l'utilisateur.
"Un bon architecte maximise le nombre de décisions non prises." Robert C. Martin
http://cleancoder.posterous.com/architecture-deference
la source
J'utilise une approche hybride - les éléments OLTP sont gérés par EF alors que les opérations lourdes telles que les insertions par lots, les mises à jour en masse, les requêtes de rapport, etc., sont gérées par les processus stockés. Cela facilite également le chemin de migration si vous ne faites pas une réécriture complète de votre couche de données en une fois.
la source