Primo codice vs Modello / Primo database [chiuso]


618

Quali sono i pro e i contro dell'utilizzo di Entity Framework 4.1 Code-first su Model / Database-first con diagramma EDMX?

Sto cercando di comprendere appieno tutti gli approcci alla costruzione del livello di accesso ai dati utilizzando EF 4.1. Sto usando il modello di repository eIoC .

So di poter usare l'approccio basato sul codice: definire manualmente le mie entità e il mio contesto e utilizzare ModelBuilder per mettere a punto lo schema.

Posso anche creare un EDMXdiagramma e scegliere un passaggio di generazione del codice che utilizza i modelli T4 per generare lo stessoPOCO classi.

In entrambi i casi finisco con un POCOoggetto che è ORMagnostico e un contesto da cui deriva DbContext.

Database-first sembra essere più interessante poiché posso progettare database in Enterprise Manager, sincronizzare rapidamente il modello e perfezionarlo utilizzando il designer.

Quindi qual è la differenza tra questi due approcci? Si tratta solo della preferenza VS2010 rispetto a Enterprise Manager?


12
Entity Framework 7 sta cadendo EDMX: msdn.microsoft.com/en-us/magazine/dn890367.aspx
CAD Bloke

5
@CADbloke Entity Framework 7 è ora Entity Framework Core 1.0
RBT

6
A tutti gli altri browser, a meno che tu non abbia un hardon per 7000 file XML lunghi e risolvi i conflitti di unione nel suddetto, vai prima al codice e risparmiati un mal di testa
Dan Pantry

3
C'è un buon resoconto di
danio

4
Quasi ogni risposta data è "Penso" ... la definizione assoluta di "Principalmente basata sull'opinione".
Lankymart,

Risposte:


703

Penso che le differenze siano:

Prima il codice

  • Molto popolare perché ai programmatori hardcore non piace alcun tipo di designer e definire la mappatura in EDMX xml è troppo complesso.
  • Pieno controllo del codice (nessun codice generato automaticamente che è difficile da modificare).
  • L'aspettativa generale è che non ti preoccupi di DB. DB è solo un archivio senza logica. EF gestirà la creazione e non vuoi sapere come fa il lavoro.
  • Le modifiche manuali al database andranno probabilmente perse perché il codice definisce il database.

Prima il database

  • Molto popolare se si dispone di DB progettati da DBA, sviluppati separatamente o se si dispone di DB esistenti.
  • Consentirai a EF di creare entità per te e dopo la modifica della mappatura genererai entità POCO.
  • Se si desidera funzionalità aggiuntive nelle entità POCO, è necessario modificare il modello T4 o utilizzare le classi parziali.
  • Modifiche manuali al database sono possibili perché il database definisce il modello di dominio. Puoi sempre aggiornare il modello dal database (questa funzione funziona abbastanza bene).
  • Lo uso spesso insieme ai progetti VS Database (solo versione Premium e Ultimate).

Prima il modello

  • IMHO popolare se sei un fan dei designer (= non ti piace scrivere codice o SQL).
  • "Disegnerai" il tuo modello e lascerai che il flusso di lavoro generi lo script del tuo database e il modello T4 generi le tue entità POCO. Perderai parte del controllo sia sulle entità che sul database, ma per piccoli progetti facili sarai molto produttivo.
  • Se si desidera funzionalità aggiuntive nelle entità POCO, è necessario modificare il modello T4 o utilizzare le classi parziali.
  • Le modifiche manuali al database andranno probabilmente perse perché il modello definisce il database. Funziona meglio se è installato il power pack di generazione del database. Ti consentirà di aggiornare lo schema del database (invece di ricrearlo) o di aggiornare i progetti del database in VS.

Mi aspetto che, nel caso di EF 4.1, ci siano molte altre funzionalità correlate a Code First vs. Model / Database. L'API fluente utilizzata prima nel codice non offre tutte le funzionalità di EDMX. Mi aspetto che funzioni come la mappatura delle procedure memorizzate, le viste delle query, la definizione delle viste, ecc. Funzionino quando si utilizza prima Modello / Database e DbContext(non l'ho ancora provato) ma non lo fanno prima in Code.


5
@Ladislav - grazie per la risposta esaustiva. Solo per chiarire: ad eccezione di alcune limitazioni delle API fluenti non ci sono reali differenze tecniche tra questi approcci? Si tratta più di sviluppo / processo di distribuzione / metodologia? Ad esempio, ho ambienti separati per Dev / Test / Beta / Prod e aggiornerò il database manualmente su Beta / Prod poiché le modifiche allo schema potrebbero richiedere alcune complesse modifiche dei dati. Con Dev / Test sono contento che EF lasci cadere e crei database mentre li seminerò con i dati di test negli inizializzatori.
Jakub Konecki,

152
Ho progettato database per così tanto tempo che non riesco a immaginare di fare prima nulla tranne il database. In effetti, scrivo ancora molte procedure memorizzate per le istruzioni select a volume più elevato e simili, quindi eseguirò una funzione di importazione nel modello EF tutto in nome della performance.
Steve Wortham,

9
Cosa intendi con dichiarazioni di selezione ad alto volume? Le procedure memorizzate non sono più veloci dei SELECT che inviano dall'applicazione.
Piotr Perak,

20
È possibile avere SQL nell'applicazione. Quel SQL sarà molto probabilmente incorporato nel codice compilato e qualsiasi modifica richiederà una ricompilazione e una ridistribuzione mentre una modifica della procedura memorizzata richiederà solo la modifica della procedura memorizzata. I clienti / i clienti / gli utenti saranno meno colpiti dalle modifiche in questo caso.
CodeWarrior

5
@JakubKonecki, qualunque cosa non trovi in ​​quella DbContextche esiste nel ObjectContextsemplice utilizzo ((IObjectContextAdapter)dbcontext).ObjectContext.
Shimmy Weitzhandler,

134

Penso che questo semplice "albero decisionale" di Julie Lerman, l'autore di "Programming Entity Framework", dovrebbe aiutare a prendere la decisione con maggiore sicurezza:

un albero decisionale per aiutare a scegliere diversi approcci con EF

Maggiori informazioni qui .


111
Questo non è completo Cosa succede se si preferisce NON utilizzare un visual designer ma si dispone di un database esistente?
Dave New,

14
Ancora peggio ... le decisioni della vita reale non sono prese dai diagrammi piuttosto che dalle limitazioni tecniche che affronti quando usi il codice in primo luogo, ad esempio non puoi creare un indice univoco su un campo o non puoi cancellare i dati gerarchici in una tabella ad albero per questo è necessario un CTE utilizzando il contesto.Table.SqlQuery ("seleziona ..."). Il modello / database prima non presenta questi inconvenienti.
Elisabeth,

32
@davenewza questo è il primo percorso non è vero?
Chris S,

3
@davenewza esistente database => classi esistenti? Codice primo: database prima :)
riadh gomri

4
@davenewza Utilizzare Powertools del framework Entity per creare le classi POCO dal DB. Codice primo di un database esistente
Iman Mahmoudinasab,

50

Il database prima e il modello prima non hanno differenze reali. Il codice generato è lo stesso e puoi combinare questi approcci. Ad esempio, è possibile creare un database utilizzando designer, quindi è possibile modificare il database utilizzando lo script sql e aggiornare il modello.

Quando si utilizza prima il codice, non è possibile modificare il modello senza un database di ricreazione e la perdita di tutti i dati. IMHO, questa limitazione è molto severa e non consente di utilizzare il codice prima nella produzione. Per ora non è veramente utilizzabile.

Il secondo svantaggio minore del codice è innanzitutto che il generatore di modelli richiede privilegi sul database principale. Ciò non influisce se si utilizza il database SQL Server Compact o se si controlla il server di database.

Il vantaggio del codice è innanzitutto un codice molto pulito e semplice. Hai il pieno controllo di questo codice e puoi facilmente modificarlo e usarlo come modello di visualizzazione.

Posso consigliare di utilizzare il primo approccio al codice quando si crea un'applicazione standalone semplice senza versioning e si utilizza prima il modello \ database nei progetti che richiedono modifiche nella produzione.


7
Se stai per aggiornare manualmente l'ambiente di produzione con script SQL, puoi comunque fare lo stesso con Code First. È sufficiente generare gli script di modifica, se necessario. Diversi strumenti possono automatizzare questi delta e puoi continuare a utilizzare Code First. Dovrai semplicemente cambiare l'inizializzatore Code First in qualcosa come CreateDatabaseIfNotExists per non eliminare il database corrente.
Esteban Brenes,

Alcune differenze stanno importando le viste e quindi rigenerando il database in cui le viste diventano tabelle. Rende difficile creare un nuovo DB e confrontarlo con il DB prod per vedere se sincronizzato.
Dave,

Model First non supporta le funzioni SQL definite dall'utente (almeno in EF4, non so se questo è cambiato). Con Database First, è possibile importare UDF e utilizzarli nelle query LINQ.
Tsahi Asher,

Nessuna differenza? Prova a importare visualizzazioni e tabelle SimpleMembership, quindi genera database dal modello e vedi cosa ottieni. Neanche vicino! Questi dovrebbero andare di andata e ritorno, ma MSFT ha sostanzialmente abbandonato MF e DF al posto di CF, che è anche incompleto in termini di utilizzo di viste e processi memorizzati.
Dave,

È possibile disabilitare il processo di ricreazione del database basato su prime migrazioni di codice ed eseguirlo manualmente nel modello e nel database. puoi farlo specificando disableDatabaseInitialization = "true" nel tuo web / app.config in <EntityFramework> ..... <contexts> <context type = "myNamespace.mydbContext", "myassemblyORProject" disableDatabaseInitialization = "true" /> </EntityFramework> Puoi eliminare la cartella delle migrazioni.
Hasteq,

37

Citando le parti rilevanti da http://www.itworld.com/development/405005/3-reasons-use-code-first-design-entity-framework

3 motivi per utilizzare la prima progettazione del codice con Entity Framework

1) Meno cruft, meno gonfia

L'uso di un database esistente per generare un file di modello .edmx e i modelli di codice associati si traducono in un enorme mucchio di codice generato automaticamente. Sei implorato di non toccare mai questi file generati per non rompere qualcosa o le tue modifiche verranno sovrascritte sulla generazione successiva. Anche il contesto e l'inizializzatore sono bloccati insieme in questo pasticcio. Quando è necessario aggiungere funzionalità ai modelli generati, come una proprietà di sola lettura calcolata, è necessario estendere la classe del modello. Questo finisce per essere un requisito per quasi tutti i modelli e si finisce con un'estensione per tutto.

Con il codice prima i tuoi modelli codificati a mano diventano il tuo database. I file esatti che stai creando sono ciò che genera la progettazione del database. Non ci sono file aggiuntivi e non è necessario creare un'estensione di classe quando si desidera aggiungere proprietà o qualsiasi altra cosa che il database non debba conoscere. Puoi semplicemente aggiungerli nella stessa classe purché segua la sintassi corretta. Diamine, puoi anche generare un file Model.edmx per visualizzare il tuo codice se vuoi.

2) Maggiore controllo

Quando si avvia DB per primi, si è in balia di ciò che viene generato per i propri modelli da utilizzare nella propria applicazione. Occasionalmente la convenzione di denominazione è indesiderabile. A volte le relazioni e le associazioni non sono proprio quello che vuoi. Altre volte relazioni non transitorie con caricamento lento causano il caos nelle risposte dell'API.

Sebbene ci sia quasi sempre una soluzione ai problemi di generazione del modello in cui potresti imbatterti, andare al primo codice ti offre un controllo completo e accurato sin dall'inizio. Puoi controllare ogni aspetto sia dei tuoi modelli di codice sia della progettazione del tuo database comodamente dall'oggetto business. È possibile specificare con precisione relazioni, vincoli e associazioni. È possibile impostare contemporaneamente limiti di caratteri di proprietà e dimensioni delle colonne del database. È possibile specificare quali raccolte correlate devono essere caricate con impazienza o non essere affatto serializzate. In breve, sei responsabile di più cose ma hai il pieno controllo del design della tua app.

3) Controllo versione database

Questo è grande. I database delle versioni sono difficili, ma con la prima codifica e la prima migrazione del codice, è molto più efficace. Poiché lo schema del database è completamente basato sui modelli di codice, in base alla versione che controlla il codice sorgente, si contribuisce alla versione del database. Sei responsabile del controllo dell'inizializzazione del contesto che può aiutarti a fare cose come seed di dati aziendali fissi. Sei anche responsabile della creazione delle prime migrazioni di codice.

Quando si abilitano per la prima volta le migrazioni, vengono generate una classe di configurazione e una migrazione iniziale. La migrazione iniziale è lo schema corrente o la linea di base v1.0. Da quel momento in poi aggiungerai le migrazioni che sono marcate con il timestamp ed etichettate con un descrittore per aiutare con l'ordine delle versioni. Quando si chiama add-migrazione dal gestore pacchetti, verrà generato un nuovo file di migrazione contenente tutto ciò che è cambiato nel modello di codice automaticamente in entrambe le funzioni SU () e GIÙ (). La funzione SU applica le modifiche al database, la funzione GIÙ rimuove le stesse modifiche nell'evento che si desidera ripristinare. Inoltre, è possibile modificare questi file di migrazione per aggiungere ulteriori modifiche come nuove viste, indici, procedure memorizzate e quant'altro. Diventeranno un vero sistema di controllo delle versioni per lo schema del database.


31

Il codice sembra essere la stella nascente. Ho dato una rapida occhiata a Ruby on Rails e il loro standard è in primo luogo il codice, con migrazioni di database.

Se stai creando un'applicazione MVC3, credo che Code abbia prima i seguenti vantaggi:

  • Facile decorazione degli attributi : puoi decorare i campi con attributi di convalida, obbligatori, ecc., È piuttosto imbarazzante con la modellazione EF
  • Nessun strano errore di modellazione : la modellazione EF presenta spesso strani errori, ad esempio quando si tenta di rinominare una proprietà di associazione, è necessario che corrisponda ai metadati sottostanti, molto poco flessibile.
  • Non imbarazzante da unire - Quando si utilizzano strumenti di controllo della versione del codice come mercurial, l'unione dei file .edmx è una seccatura. Sei un programmatore abituato a C # e lì stai unendo un .edmx. Non così con code-first.
  • Contrasta prima con Code e hai il controllo completo senza tutte le complessità nascoste e le incognite da affrontare.
  • Ti consiglio di utilizzare lo strumento da riga di comando di Package Manager, non utilizzare nemmeno gli strumenti grafici per aggiungere un nuovo controller alle viste dello scaffold.
  • DB-Migrations - Quindi puoi anche abilitare-Migrations. Questo è così potente. Apportare modifiche al modello nel codice, quindi il framework può tenere traccia delle modifiche allo schema, in modo da poter distribuire senza problemi gli aggiornamenti, con le versioni dello schema aggiornate automaticamente (e declassate se necessario). (Non sono sicuro, ma questo probabilmente funziona anche con il modello prima)

Aggiornare

La domanda richiede anche un confronto tra code-first e EDMX model / db-first. Code-first può essere utilizzato anche per entrambi questi approcci:


3
Model-first non sta codificando prima il POCO, questo è Code First, Model-First è un Visual Designer per generare automaticamente POCO e successivamente generare database dal modello.
Diego Mendes,

Al giorno d'oggi in entrambi i percorsi visivi e di codice, è possibile eseguire prima "Modello" o "Database". Il primo è la progettazione manuale (tramite codice o editor visivo), il secondo è la creazione di un database e la creazione del modello (POCO o EDMX).
Todd,

11

Uso prima il database EF per fornire maggiore flessibilità e controllo sulla configurazione del database.

Inizialmente il codice EF e il modello sembravano interessanti e forniscono l'indipendenza del database, tuttavia nel fare ciò non consente di specificare ciò che considero informazioni di configurazione del database molto basilari e comuni. Ad esempio indici di tabella, metadati di sicurezza o avere una chiave primaria contenente più di una colonna. Trovo di voler utilizzare queste e altre funzionalità di database comuni e quindi devo fare comunque una configurazione del database direttamente.

Trovo che le classi POCO predefinite generate durante il DB siano molto pulite, tuttavia mancano degli attributi di annotazione dei dati molto utili o delle mappature sulle procedure memorizzate. Ho usato i modelli T4 per superare alcune di queste limitazioni. I modelli T4 sono fantastici, specialmente se combinati con i tuoi metadati e le classi parziali.

Il modello sembra inizialmente avere molto potenziale, ma mi sta dando molti bug durante il refactoring di schemi di database complessi. Non so perché.


4
È possibile definire prima le chiavi composite utilizzando il codice - stackoverflow.com/questions/5466374/…
Jakub Konecki,

3
Per i lettori futuri, questo non è più il caso, è possibile aggiungere indici, chiavi primarie a più colonne e questo tipo di cose in EF Code First.
tobiak777,

1
L'EF avrebbe dovuto essere risolto in modo che tutti e 3 gli approcci potessero essere usati in modo intercambiabile nello stesso database in quanto vi sono vantaggi e svantaggi per tutti e 3 gli approcci
Dave,

Inoltre la verità della prima soluzione di codice non ideale Sto usando prima il database a causa della migrazione ad altri IDE / Lingua in futuro e voglio avere una struttura di database solida e integrata, un altro fatto che preferisco prima il database è la flessibilità nel cambiare qualsiasi parte di archivio dati.
QMaster

7

Lavorare con modelli di grandi dimensioni era molto lento prima dell'SP1 (non l'ho provato dopo l'SP1, ma ora si dice che è un gioco da ragazzi).

Progetto ancora prima i miei tavoli, quindi uno strumento interno genera i POCO per me, quindi mi fa carico di svolgere attività ripetitive per ogni oggetto poco.

quando usi i sistemi di controllo del codice sorgente, puoi facilmente seguire la cronologia dei tuoi POCO, non è così facile con il codice generato dal designer.

Ho una base per il mio POCO, che rende molte cose abbastanza facili.

Ho viste per tutte le mie tabelle, ogni vista di base porta informazioni di base per le mie chiavi esterne e i miei POCO di vista derivano dalle mie classi POCO, che è di nuovo molto utile.

E infine non mi piacciono i designer.


8
"quando usi i sistemi di controllo del codice sorgente, puoi facilmente seguire la cronologia dei tuoi POCO, non è così facile con il codice generato dal designer." - Conservo il codice generato dal designer nel controllo del codice sorgente, quindi posso sempre visualizzare la cronologia.
Jakub Konecki,

1
@JakubKonecki Hai mai provato a unire file EDMX in un team di 3+ ​​persone? È solo un dolore ... Invece le persone cercano di evitare la fusione e prendono semplicemente l'altra revisione e ripetono le proprie modifiche, perché la fusione tende a fallire in un file generato automaticamente con migliaia di righe di XML.
bytecode77

6

Esempio di primo approccio al database:

Senza scrivere alcun codice: ASP.NET MVC / MVC3 Database First Approach / Database first

E penso che sia meglio di altri approcci perché la perdita di dati è inferiore con questo approccio.


Potresti approfondire l'esistenza di una "minore perdita di dati" con il primo approccio di DB? Come eseguiresti la trasformazione dei dati se dovessi dividere la tabella esistente in due?
Jakub Konecki,

probabilmente finiresti per scrivere uno script sql che si occupa della trasformazione. In generale, MS ha annunciato di migliorare la migrazione dei dati di Code First con la sua nuova versione, quindi questo potrebbe non essere un argomento in futuro.
ckonig,

Il problema con il database è innanzitutto che la progettazione del database ha generalmente astrazioni errate che colano nel modello ... tabelle di giunzione, ecc. Il compito del database è semplicemente quello di mantenere il modello.
Nerdfest,

Questa "risposta" è un'opinione basata senza carne sul tuo argomento, una frase non prende posizione.
TravisO,

Potresti approfondire l'esistenza di una "minore perdita di dati" con il primo approccio di DB?
amal50,

4

IMHO Penso che tutti i modelli abbiano un ottimo posto, ma il problema che ho con il primo approccio al modello è che in molte grandi aziende con DBA che controlla i database non si ottiene la flessibilità di costruire applicazioni senza usare i primi approcci al database. Ho lavorato su molti progetti e quando si trattava di implementare volevano il pieno controllo.

Quindi, per quanto io sia d'accordo con tutte le possibili variazioni Codice primo, Modello primo, Database prima, è necessario considerare l'ambiente di produzione effettivo. Quindi, se il tuo sistema sarà un'applicazione di base di utenti di grandi dimensioni con molti utenti e DBA che eseguono lo spettacolo, potresti considerare la prima opzione Database solo la mia opinione.


Hai ragione. La SM ha dato ai programmatori approcci diversi perché i re sono scenari diversi. Dovresti sapere tutto e decidere in base al tuo scenario quale sia il migliore per il progetto, e poi cosa ti piace di più.
Sterling Diaz,

0

Penso che uno dei vantaggi del codice sia innanzitutto che è possibile eseguire il backup di tutte le modifiche apportate a un sistema di controllo della versione come Git. Poiché tutte le tabelle e le relazioni sono archiviate in quelle che sono essenzialmente solo classi, puoi tornare indietro nel tempo e vedere quale era la struttura del tuo database prima.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.