Code-first vs Model / Database-first [fermé]

618

Quels sont les avantages et les inconvénients d'utiliser Entity Framework 4.1 Code-first sur Model / Database-first avec diagramme EDMX?

J'essaie de comprendre pleinement toutes les approches pour créer une couche d'accès aux données à l'aide d'EF 4.1. J'utilise le modèle de référentiel et IoC.

Je sais que je peux utiliser l'approche du code en premier: définir mes entités et mon contexte à la main et utiliser ModelBuilderpour affiner le schéma.

Je peux également créer un EDMXdiagramme et choisir une étape de génération de code qui utilise des modèles T4 pour générer les mêmes POCOclasses.

Dans les deux cas, je me retrouve avec un POCOobjet ORMagnostique et le contexte qui en découle DbContext.

La base de données en premier semble être la plus attrayante car je peux concevoir une base de données dans Enterprise Manager, synchroniser rapidement le modèle et l'affiner à l'aide du concepteur.

Quelle est donc la différence entre ces deux approches? S'agit-il simplement de la préférence VS2010 par rapport à Enterprise Manager?

Jakub Konecki
la source
12
Entity Framework 7 supprime EDMX: msdn.microsoft.com/en-us/magazine/dn890367.aspx
CAD bloke
5
@CADbloke Entity Framework 7 est désormais Entity Framework Core 1.0
RBT
6
Pour tous les autres navigateurs, à moins que vous n'ayez un hardon pour 7000 fichiers XML longs et que vous résolviez les conflits de fusion dans ce qui précède, allez d'abord coder et évitez les maux de tête
Dan Pantry
3
Il y a un bon article de janvier 2015 sur les trois approches sur roland.kierkels.net/c-asp-net/…
danio
4
Presque toutes les réponses données sont "Je pense" ... la définition absolue de "Principalement basé sur l'opinion".
Lankymart

Réponses:

703

Je pense que les différences sont:

Code d'abord

  • Très populaire parce que les programmeurs inconditionnels n'aiment aucun type de concepteurs et définir le mappage dans EDMX xml est trop complexe.
  • Contrôle total sur le code (pas de code généré automatiquement difficile à modifier).
  • L'attente générale est que vous ne vous embêtez pas avec DB. DB est juste un stockage sans logique. EF gérera la création et vous ne voulez pas savoir comment cela fonctionne.
  • Les modifications manuelles de la base de données seront très probablement perdues car votre code définit la base de données.

Base de données d'abord

  • Très populaire si vous avez une DB conçue par des DBA, développée séparément ou si vous avez une DB existante.
  • Vous laisserez EF créer des entités pour vous et après modification du mappage, vous générerez des entités POCO.
  • Si vous souhaitez des fonctionnalités supplémentaires dans les entités POCO, vous devez soit modifier le modèle T4, soit utiliser des classes partielles.
  • Des modifications manuelles de la base de données sont possibles car la base de données définit votre modèle de domaine. Vous pouvez toujours mettre à jour le modèle à partir de la base de données (cette fonctionnalité fonctionne très bien).
  • J'utilise souvent cela ensemble avec des projets VS Database (uniquement les versions Premium et Ultimate).

Modèle d'abord

  • IMHO populaire si vous êtes fan de concepteur (= vous n'aimez pas écrire du code ou SQL).
  • Vous "dessinez" votre modèle et laissez le workflow générer votre script de base de données et le modèle T4 générer vos entités POCO. Vous perdrez une partie du contrôle sur vos entités et votre base de données, mais pour les petits projets faciles, vous serez très productif.
  • Si vous souhaitez des fonctionnalités supplémentaires dans les entités POCO, vous devez soit modifier le modèle T4, soit utiliser des classes partielles.
  • Les modifications manuelles de la base de données seront probablement perdues car votre modèle définit la base de données. Cela fonctionne mieux si vous avez installé un bloc d'alimentation de génération de base de données. Il vous permettra de mettre à jour le schéma de la base de données (au lieu de recréer) ou de mettre à jour les projets de base de données dans VS.

Je m'attends à ce que dans le cas d'EF 4.1, il existe plusieurs autres fonctionnalités liées à Code First vs Model / Database first. L'API Fluent utilisée dans Code en premier ne propose pas toutes les fonctionnalités d'EDMX. Je m'attends à ce que des fonctionnalités telles que le mappage de procédures stockées, les vues de requête, la définition de vues, etc. fonctionnent lors de l'utilisation de Model / Database en premier et DbContext(je ne l'ai pas encore essayé) mais elles ne le font pas en premier dans Code.

Ladislav Mrnka
la source
5
@Ladislav - merci pour la réponse complète. Juste pour clarifier: à part quelques limitations de l'API fluide, il n'y a pas de réelles différences techniques entre ces approches? C'est plus sur le processus / la méthodologie de développement / déploiement? Par exemple, j'ai des environnements distincts pour Dev / Test / Beta / Prod et je mettrai à niveau la base de données manuellement sur Beta / Prod car les modifications du schéma peuvent nécessiter des modifications de données complexes. Avec Dev / Test, je suis heureux qu'EF supprime et crée des bases de données, car je les graverai moi-même avec les données de test dans les initialiseurs.
Jakub Konecki
152
Je conçois des bases de données depuis si longtemps que je n'arrive pas à imaginer faire autre chose que des bases de données en premier. En fait, j'écris encore beaucoup de procédures stockées pour les instructions de sélection de volume plus élevé et autres, puis je ferai une importation de fonction dans le modèle EF au nom de la performance.
Steve Wortham
9
Qu'entendez-vous par des déclarations de sélection à volume élevé? Les procédures stockées ne sont pas plus rapides que les SELECT envoyés depuis l'application.
Piotr Perak
20
Vous pouvez avoir SQL dans votre application. Ce SQL sera très probablement incorporé dans le code compilé, et toute modification nécessitera une recompilation et un redéploiement tandis qu'une modification de procédure stockée nécessitera simplement la modification de la procédure stockée. Les clients / clients / utilisateurs seront moins touchés par les changements dans ce cas.
CodeWarrior
5
@JakubKonecki, tout ce que vous ne trouvez pas dans le DbContextqui existe ObjectContextsimplement ((IObjectContextAdapter)dbcontext).ObjectContext.
Shimmy Weitzhandler
134

Je pense que ce simple "arbre de décision" de Julie Lerman, l'auteur de "Programming Entity Framework" devrait aider à prendre la décision avec plus de confiance:

un arbre de décision pour aider à choisir différentes approches avec EF

Plus d'infos ici .

Bahador Izadpanah
la source
111
Ce n'est pas complet. Que se passe-t-il si vous préférez NE PAS utiliser un concepteur visuel mais que vous avez une base de données existante?
Dave New
14
Pire encore ... les décisions réelles ne sont pas prises par des diagrammes plutôt que par des limitations techniques auxquelles vous êtes confronté lorsque vous utilisez le code en premier, par exemple, vous ne pouvez pas créer un index unique sur un champ ou vous ne pouvez pas supprimer des données hiérarchiques dans une table arborescente pour cela vous besoin d'un CTE utilisant le context.Table.SqlQuery ("select ..."). Le modèle / base de données ne présente tout d'abord pas ces inconvénients.
Elisabeth
32
@davenewza c'est le premier chemin n'est-ce pas?
Chris S
3
@davenewza existing database => classes existantes? Code First: Database first :)
riadh gomri
4
@davenewza Utilisez le framework Entity Powertools pour créer vos classes POCO à partir de DB. Code d'abord vers une base de données existante
Iman Mahmoudinasab
50

La base de données d'abord et le modèle d'abord n'ont pas de réelles différences. Le code généré est le même et vous pouvez combiner ces approches. Par exemple, vous pouvez créer une base de données à l'aide de Designer, que vous pouvez modifier la base de données à l'aide du script SQL et mettre à jour votre modèle.

Lorsque vous utilisez d'abord du code, vous ne pouvez pas modifier le modèle sans base de données de loisirs et perdre toutes les données. À mon humble avis, cette limitation est très stricte et ne permet pas d'utiliser le code d'abord en production. Pour l'instant, ce n'est pas vraiment utilisable.

Le deuxième inconvénient mineur du code est que le constructeur de modèles requiert des privilèges sur la base de données principale. Cela ne vous affecte pas si vous utilisez la base de données SQL Server Compact ou si vous contrôlez le serveur de base de données.

L'avantage du code est d'abord un code très propre et simple. Vous avez le contrôle total de ce code et pouvez facilement le modifier et l'utiliser comme modèle de vue.

Je peux recommander d'utiliser l'approche de code en premier lorsque vous créez une application autonome simple sans versionner et en utilisant model \ database d'abord dans des projets qui nécessitent une modification en production.

Stepan Smagin
la source
7
Si vous allez mettre à jour manuellement l'environnement de production avec des scripts SQL, vous pouvez toujours faire de même avec Code First. Vous générez simplement les scripts de modification si nécessaire. Plusieurs outils peuvent automatiser ces deltas et vous pouvez continuer à utiliser Code First. Vous aurez simplement besoin de changer l'initialiseur Code First en quelque chose comme CreateDatabaseIfNotExists afin de ne pas supprimer la base de données actuelle.
Esteban Brenes
Certaines différences importent des vues puis régénèrent la base de données où les vues deviennent des tables. Il est difficile de générer une nouvelle base de données et de la comparer à la base de données de prod pour voir si elle est synchronisée.
Dave
Model First ne prend pas en charge les fonctions SQL définies par l'utilisateur (au moins dans EF4, je ne sais pas si cela a changé). Avec Database First, vous pouvez importer des FDU et les utiliser dans vos requêtes LINQ.
Tsahi Asher du
Pas de différences? Essayez d'importer des vues et des tables SimpleMembership, puis générez une base de données à partir du modèle et voyez ce que vous obtenez. Pas même près! Ceux-ci devraient aller-retour, mais MSFT a essentiellement abandonné MF et DF au lieu de CF, ce qui est également incomplet en termes d'utilisation des vues et des processus stockés.
Dave
Vous pouvez désactiver le processus de recréation de base de données basé sur les premières migrations de code et le faire manuellement dans le modèle et la base de données. vous pouvez le faire en spécifiant disableDatabaseInitialization = "true" dans votre web / app.config à <EntityFramework> ..... <contexts> <context type = "myNamespace.mydbContext", "myassemblyORProject" disableDatabaseInitialization = "true" /> </EntityFramework> Vous pouvez supprimer le dossier des migrations.
Hasteq
37

Citant les parties pertinentes de http://www.itworld.com/development/405005/3-reasons-use-code-first-design-entity-framework

3 raisons d'utiliser le code first design avec Entity Framework

1) Moins de larves, moins de ballonnement

L'utilisation d'une base de données existante pour générer un fichier de modèle .edmx et les modèles de code associés génère une pile géante de code généré automatiquement. Vous êtes imploré de ne jamais toucher à ces fichiers générés de peur de casser quelque chose ou de remplacer vos modifications par la génération suivante. Le contexte et l'initialiseur sont également coincés dans ce gâchis. Lorsque vous devez ajouter des fonctionnalités à vos modèles générés, comme une propriété en lecture seule calculée, vous devez étendre la classe de modèle. Cela finit par être une exigence pour presque tous les modèles et vous vous retrouvez avec une extension pour tout.

Avec le code d'abord, vos modèles codés à la main deviennent votre base de données. Les fichiers exacts que vous créez sont ce qui génère la conception de la base de données. Il n'y a pas de fichiers supplémentaires et il n'est pas nécessaire de créer une extension de classe lorsque vous souhaitez ajouter des propriétés ou tout autre élément que la base de données n'a pas besoin de connaître. Vous pouvez simplement les ajouter dans la même classe tant que vous suivez la syntaxe appropriée. Heck, vous pouvez même générer un fichier Model.edmx pour visualiser votre code si vous le souhaitez.

2) Plus de contrôle

Lorsque vous accédez à la base de données en premier, vous êtes à la merci de ce qui est généré pour vos modèles à utiliser dans votre application. Parfois, la convention de dénomination n'est pas souhaitable. Parfois, les relations et les associations ne sont pas tout à fait ce que vous voulez. D'autres fois, les relations non transitoires avec le chargement paresseux font des ravages sur vos réponses API.

Bien qu'il existe presque toujours une solution aux problèmes de génération de modèles que vous pourriez rencontrer, le code en premier vous donne un contrôle complet et fin dès le départ. Vous pouvez contrôler tous les aspects de vos modèles de code et de la conception de votre base de données dans le confort de votre objet métier. Vous pouvez spécifier précisément les relations, les contraintes et les associations. Vous pouvez définir simultanément des limites de caractères de propriété et des tailles de colonne de base de données. Vous pouvez spécifier quelles collections liées doivent être chargées avec impatience ou ne pas être sérialisées du tout. En bref, vous êtes responsable de plus de choses, mais vous contrôlez entièrement la conception de votre application.

3) Contrôle de version de la base de données

C'est un gros problème. La gestion des versions des bases de données est difficile, mais avec les migrations de code d'abord et de code d'abord, c'est beaucoup plus efficace. Parce que votre schéma de base de données est entièrement basé sur vos modèles de code, en contrôlant la version de votre code source, vous contribuez à la version de votre base de données. Vous êtes responsable du contrôle de l'initialisation de votre contexte, ce qui peut vous aider à effectuer des opérations telles que l'amorçage de données commerciales fixes. Vous êtes également responsable de la création des premières migrations de code.

Lorsque vous activez pour la première fois les migrations, une classe de configuration et une migration initiale sont générées. La migration initiale est votre schéma actuel ou votre ligne de base v1.0. À partir de ce moment, vous ajouterez des migrations horodatées et étiquetées avec un descripteur pour faciliter la commande des versions. Lorsque vous appelez add-migration à partir du gestionnaire de packages, un nouveau fichier de migration sera généré contenant tout ce qui a changé dans votre modèle de code automatiquement dans une fonction UP () et DOWN (). La fonction UP applique les modifications à la base de données, la fonction DOWN supprime ces mêmes modifications dans le cas où vous souhaitez annuler. De plus, vous pouvez modifier ces fichiers de migration pour ajouter des modifications supplémentaires telles que de nouvelles vues, index, procédures stockées, etc. Ils deviendront un véritable système de gestion des versions pour votre schéma de base de données.

Dit Roohullah Allem
la source
31

Le code en premier semble être l'étoile montante. J'ai jeté un coup d'œil à Ruby on Rails, et leur standard est le code en premier, avec les migrations de base de données.

Si vous construisez une application MVC3, je pense que le code présente d'abord les avantages suivants:

  • Décoration d'attribut facile - Vous pouvez décorer des champs avec des attributs de validation, d'exigence, etc., c'est assez gênant avec la modélisation EF
  • Pas d'erreurs de modélisation étranges - La modélisation EF comporte souvent des erreurs étranges, comme lorsque vous essayez de renommer une propriété d'association, elle doit correspondre aux métadonnées sous-jacentes - très rigide.
  • Pas gênant de fusionner - Lorsque vous utilisez des outils de contrôle de version de code tels que mercurial, la fusion de fichiers .edmx est pénible. Vous êtes un programmeur habitué au C #, et là vous fusionnez un .edmx. Ce n'est pas le cas avec le code d'abord.
  • Contrastez d'abord avec Code et vous avez un contrôle complet sans toutes les complexités cachées et les inconnues à gérer.
  • Je vous recommande d'utiliser l'outil de ligne de commande du Gestionnaire de packages, n'utilisez même pas les outils graphiques pour ajouter un nouveau contrôleur aux vues d'échafaudage.
  • DB-Migrations - Ensuite, vous pouvez également activer les migrations. C'est tellement puissant. Vous apportez des modifications à votre modèle dans le code, puis le cadre peut suivre les modifications de schéma, vous pouvez donc déployer de façon transparente les mises à niveau, avec les versions de schéma automatiquement mises à niveau (et rétrogradées si nécessaire). (Je ne sais pas, mais cela fonctionne probablement aussi avec le modèle d'abord)

Mise à jour

La question demande également une comparaison du code en premier au modèle EDMX / db en premier. Le code en premier peut également être utilisé pour ces deux approches:

Todd
la source
3
Model-first ne code pas d'abord le POCO, c'est Code First, Model-First est un concepteur visuel pour générer automatiquement des POCO et ensuite générer des bases de données à partir du modèle.
Diego Mendes
De nos jours, dans les routes visuelles et de code, vous pouvez d'abord faire "Model" ou "Database" en premier. Le premier est la conception manuelle (soit via le code ou l'éditeur visuel), le second est la construction d'une base de données et la création du modèle (POCO ou EDMX).
Todd
11

J'utilise d'abord la base de données EF afin de fournir plus de flexibilité et de contrôle sur la configuration de la base de données.

Le code EF en premier et le modèle semblaient d'abord cool au premier abord, et offrent une indépendance vis-à-vis de la base de données, mais ce faisant, il ne vous permet pas de spécifier ce que je considère comme des informations de configuration de base de données très basiques et courantes. Par exemple, des index de table, des métadonnées de sécurité ou une clé primaire contenant plusieurs colonnes. Je trouve que je veux utiliser ces fonctionnalités et d'autres fonctionnalités de base de données courantes et que je dois donc faire une configuration de base de données directement de toute façon.

Je trouve que les classes POCO par défaut générées pendant la base de données sont d'abord très propres, mais manquent d'attributs d'annotation de données très utiles, ou de mappages aux procédures stockées. J'ai utilisé les modèles T4 pour surmonter certaines de ces limitations. Les modèles T4 sont impressionnants, surtout lorsqu'ils sont combinés avec vos propres métadonnées et classes partielles.

Le modèle semble d'abord avoir beaucoup de potentiel, mais me donne beaucoup de bugs lors du refactoring de schéma de base de données complexe. Pas certain de pourquoi.

user1618371
la source
4
Vous pouvez définir des clés composites en utilisant d'abord le code - stackoverflow.com/questions/5466374/…
Jakub Konecki
3
Pour les futurs lecteurs, ce n'est plus le cas, vous pouvez ajouter des index, des clés primaires multi-colonnes et ce genre de choses dans EF Code First.
tobiak777
1
EF devrait avoir été corrigé afin que les 3 approches puissent être utilisées de manière interchangeable sur la même base de données car il y a des avantages et des inconvénients pour les 3 approches
Dave
De plus, la vérité d'une solution non idéale en premier code J'utilise d'abord la base de données en raison de la migration vers un autre IDE / langage à l'avenir et je veux avoir une structure de base de données solide et intégrée, un autre fait que je préfère en premier est la flexibilité pour changer n'importe quelle partie de stockage de données.
QMaster
7

Travailler avec de gros modèles était très lent avant le SP1, (je ne l'ai pas essayé après le SP1, mais on dit que c'est un jeu d'enfant maintenant).

Je conçois toujours mes tables en premier, puis un outil construit en interne génère les POCO pour moi, donc cela prend le fardeau de faire des tâches répétitives pour chaque objet poco.

lorsque vous utilisez des systèmes de contrôle de source, vous pouvez facilement suivre l'historique de vos POCO, ce n'est pas si simple avec du code généré par le concepteur.

J'ai une base pour mon POCO, ce qui rend beaucoup de choses assez faciles.

J'ai des vues pour toutes mes tables, chaque vue de base apporte des informations de base pour mes clés étrangères et mes vues POCO dérivent de mes classes POCO, ce qui est encore très utile.

Et finalement, je n'aime pas les designers.

hazimdikenli
la source
8
"Lorsque vous utilisez des systèmes de contrôle de source, vous pouvez facilement suivre l'historique de vos POCO, ce n'est pas si simple avec du code généré par le concepteur." - Je garde le code généré par le concepteur dans le contrôle de source, afin que je puisse toujours voir l'historique.
Jakub Konecki
1
@JakubKonecki Avez-vous déjà essayé de fusionner des fichiers EDMX dans une équipe de 3 personnes ou plus? C'est juste une douleur ... Au lieu de cela, les gens essaient d'éviter la fusion et prennent simplement l'autre révision et répètent leurs propres modifications, car la fusion est susceptible d'échouer dans un fichier généré automatiquement avec des milliers de lignes de XML.
bytecode77
6

Exemple de première approche de base de données:

Sans écrire de code: ASP.NET MVC / MVC3 Database First Approche / Database first

Et je pense que c'est mieux que d'autres approches car la perte de données est moindre avec cette approche.

AukI
la source
Pourriez-vous nous expliquer qu'il y a «moins de perte de données» avec la première approche DB? Comment effectueriez-vous la transformation des données si vous deviez diviser la table existante en deux?
Jakub Konecki
vous finiriez probablement par écrire un script sql qui prend en charge la transformation. En général, MS a annoncé l'amélioration de la migration des données Code First avec leur nouvelle version, ce qui pourrait ne pas être un argument à l'avenir.
ckonig
Le problème avec la base de données est d'abord que la conception de la base de données comporte généralement des abstractions défectueuses qui s'infiltrent dans votre modèle ... tables de jonction, etc. Le travail de la base de données consiste simplement à conserver votre modèle.
Nerdfest
Cette "réponse" est une opinion basée sans viande sur votre argument, une phrase ne fait pas de position.
TravisO
Pourriez-vous nous expliquer qu'il y a «moins de perte de données» avec la première approche DB?
amal50
4

À mon humble avis, je pense que tous les modèles ont une grande place, mais le problème que j'ai avec l'approche du premier modèle est dans de nombreuses grandes entreprises avec DBA contrôlant les bases de données, vous n'obtenez pas la flexibilité de créer des applications sans utiliser les premières approches de base de données. J'ai travaillé sur de nombreux projets et en matière de déploiement, ils voulaient un contrôle total.

Donc, même si je suis d'accord avec toutes les variantes possibles Code First, Model First, Database First, vous devez tenir compte de l'environnement de production réel. Donc, si votre système va être une grande application de base d'utilisateurs avec de nombreux utilisateurs et DBA exécutant le spectacle, vous pouvez envisager la première option de base de données à mon avis.

Matthew Parton
la source
Tu as raison. MS a donné aux programmeurs différentes approches car il s'agit de scénarios différents. Vous devez tout savoir et décider en fonction de votre scénario ce qui convient le mieux au projet, puis ce que vous aimez le plus.
Sterling Diaz
0

Je pense que l'un des avantages du code est que vous pouvez sauvegarder toutes les modifications que vous avez apportées à un système de contrôle de version comme Git. Étant donné que toutes vos tables et relations sont stockées dans des classes qui ne sont essentiellement que des classes, vous pouvez remonter dans le temps et voir quelle était la structure de votre base de données auparavant.

anonymous_dojo
la source