Code-first vs Model / Database-first [fechado]

618

Quais são os prós e os contras do uso do Entity Framework 4.1 Code-first over Model / Database-first com diagrama EDMX?

Estou tentando entender completamente todas as abordagens para criar a camada de acesso a dados usando o EF 4.1. Estou usando o padrão Repository e IoC.

Sei que posso usar a abordagem de primeiro código: defina minhas entidades e contexto manualmente e use-os ModelBuilderpara ajustar o esquema.

Também posso criar um EDMXdiagrama e escolher uma etapa de geração de código que use modelos T4 para gerar as mesmas POCOclasses.

Em ambos os casos, acabo com POCOobjetos ORMagnósticos e contextos dos quais deriva DbContext.

O primeiro banco de dados parece ser mais atraente, pois eu posso projetar o banco de dados no Enterprise Manager, sincronizar rapidamente o modelo e ajustá-lo usando o designer.

Então, qual é a diferença entre essas duas abordagens? É apenas sobre a preferência VS2010 vs Enterprise Manager?

Jakub Konecki
fonte
12
O Entity Framework 7 está descartando o EDMX: msdn.microsoft.com/en-us/magazine/dn890367.aspx
CAD bloke
5
@CADbloke Entity Framework 7 já está Entity Framework Core 1.0
RBT
6
Para outros navegadores, a menos que você tem uma ereção para 7000 arquivos longa XML e resolver conflitos de mesclagem no já mencionado, código de ir primeiro e salve-se uma dor de cabeça
Dan Pantry
3
Há uma boa descrição de
danio
4
Quase todas as respostas dadas são "Eu acho" ... a definição absoluta de "Basicamente baseadas em opiniões".
precisa saber é o seguinte

Respostas:

703

Eu acho que as diferenças são:

Codifique primeiro

  • Muito popular porque os programadores hardcore não gostam de nenhum tipo de designer e a definição de mapeamento no EDMX xml é muito complexa.
  • Controle total sobre o código (nenhum código gerado automaticamente e difícil de modificar).
  • A expectativa geral é que você não se incomode com o DB. DB é apenas um armazenamento sem lógica. A EF cuidará da criação e você não deseja saber como ela funciona.
  • As alterações manuais no banco de dados provavelmente serão perdidas porque seu código define o banco de dados.

Primeiro banco de dados

  • Muito popular se você tiver um DB projetado por DBAs, desenvolvido separadamente ou se você tiver um DB existente.
  • Você permitirá que o EF crie entidades para você e após a modificação do mapeamento, você gerará entidades POCO.
  • Se você deseja recursos adicionais em entidades POCO, deve modificar o modelo T4 ou usar classes parciais.
  • Alterações manuais no banco de dados são possíveis porque o banco de dados define seu modelo de domínio. Você sempre pode atualizar o modelo do banco de dados (esse recurso funciona muito bem).
  • Costumo usar isso juntos projetos de banco de dados do VS (somente versões Premium e Ultimate).

Modele primeiro

  • IMHO popular se você é fã de designer (= você não gosta de escrever código ou SQL).
  • Você "desenhará" seu modelo e permitirá que o fluxo de trabalho gere seu script de banco de dados e o modelo T4 gere suas entidades POCO. Você perderá parte do controle em suas entidades e no banco de dados, mas para projetos pequenos e fáceis, você será muito produtivo.
  • Se você deseja recursos adicionais em entidades POCO, deve modificar o modelo T4 ou usar classes parciais.
  • As alterações manuais no banco de dados provavelmente serão perdidas porque seu modelo define o banco de dados. Isso funciona melhor se você tiver o power pack de geração de banco de dados instalado. Isso permitirá que você atualize o esquema do banco de dados (em vez de recriar) ou atualize os projetos de banco de dados no VS.

Espero que, no caso da EF 4.1, existam vários outros recursos relacionados ao Code First vs. Model / Database primeiro. A API fluente usada no Code primeiro não oferece todos os recursos do EDMX. Espero que recursos como mapeamento de procedimentos armazenados, visualizações de consulta, definição de visualizações etc. funcionem ao usar o Modelo / Banco de Dados primeiro e DbContext(ainda não o testei), mas não no Código primeiro.

Ladislav Mrnka
fonte
5
@ Ladislav - obrigado pela resposta abrangente. Apenas para esclarecer: com exceção de algumas limitações da API fluente, não há diferenças técnicas reais entre essas abordagens? É mais sobre desenvolvimento / processo de implantação / metodologia? Por exemplo, tenho ambientes separados para Dev / Test / Beta / Prod e atualizarei o banco de dados manualmente no Beta / Prod, pois as alterações no esquema podem exigir algumas modificações complexas nos dados. Com o Dev / Test, fico feliz que a EF elimine e crie bancos de dados, pois eu os propharei com dados de teste nos inicializadores.
Jakub Konecki 27/03
152
Estou projetando bancos de dados há tanto tempo que parece que nunca consigo imaginar fazer nada além de banco de dados. De fato, ainda escrevo muitos procedimentos armazenados para as instruções de seleção de volume mais alto e tal, e depois faço uma importação de função para o modelo EF, tudo em nome do desempenho.
Steve Wortham
9
O que você quer dizer com instruções de seleção de alto volume? Os procedimentos armazenados não são mais rápidos que os SELECTs enviam do aplicativo.
Piotr Perak
20
Você pode ter SQL em seu aplicativo. É provável que o SQL seja incorporado no código compilado e quaisquer alterações exigirão uma recompilação e reimplementação, enquanto uma alteração no Procedimento Armazenado exigirá apenas a edição do Procedimento Armazenado. Clientes / clientes / usuários serão menos impactados por alterações neste caso.
precisa
5
@JakubKonecki, o que você não encontrar no DbContextque existe ObjectContextsimplesmente use ((IObjectContextAdapter)dbcontext).ObjectContext.
Shimmy Weitzhandler
134

Penso que esta simples "árvore de decisão" de Julie Lerman, autora de "Programming Entity Framework", deve ajudar a tomar a decisão com mais confiança:

uma árvore de decisão para ajudar a escolher diferentes abordagens com a EF

Mais informações aqui .

Bahador Izadpanah
fonte
111
Isto não está completo. E se você preferir NÃO usar um designer visual, mas você possui um banco de dados existente?
Dave New
14
Pior ainda ... as decisões da vida real não são tomadas por diagramas, e sim pelas limitações técnicas que você enfrenta ao usar o código primeiro; por exemplo, você não pode criar um índice exclusivo em um campo ou não pode excluir dados hierárquicos em uma tabela em árvore. precisa de um CTE usando o context.Table.SqlQuery ("select ..."). O modelo / banco de dados primeiro não possui essas desvantagens.
Elisabeth
32
@davenewza esse é o primeiro caminho, não é?
Chris S
3
@davenewza banco de dados existente => classes existentes? Code First: Database first :)
riadh gomri
4
@davenewza Use o Powertools da estrutura de entidades para criar suas classes POCO a partir do DB. Code First para um banco de dados existente
Iman Mahmoudinasab
50

O banco de dados primeiro e o modelo primeiro não têm diferenças reais. O código gerado é o mesmo e você pode combinar essas abordagens. Por exemplo, você pode criar um banco de dados usando o designer, além de alterar o banco de dados usando o script sql e atualizar seu modelo.

Ao usar o código primeiro, não é possível alterar o modelo sem o banco de dados de recreação e a perda de todos os dados. IMHO, essa limitação é muito rigorosa e não permite usar o código primeiro na produção. Por enquanto não é realmente utilizável.

A segunda desvantagem menor do código é que o construtor de modelos exige privilégios no banco de dados mestre. Isso não afeta você se você estiver usando o banco de dados SQL Server Compact ou se você controla o servidor de banco de dados.

A vantagem do código primeiro é um código muito limpo e simples. Você tem controle total desse código e pode modificá-lo e usá-lo facilmente como seu modelo de exibição.

Posso recomendar o uso da primeira abordagem de código ao criar um aplicativo autônomo simples sem controle de versão e usar model \ database primeiro em projetos que exigem modificação na produção.

Stepan Smagin
fonte
7
Se você estiver atualizando manualmente o ambiente de produção com scripts SQL, ainda poderá fazer o mesmo com o Code First. Você simplesmente gera os scripts de mudança, conforme necessário. Várias ferramentas podem automatizar esses deltas e você pode continuar usando o Code First. Você só precisa alterar o inicializador do Code First para algo como CreateDatabaseIfNotExists para não excluir o banco de dados atual.
Esteban Brenes
Algumas diferenças estão importando visualizações e, em seguida, regenerando o banco de dados em que as visualizações se tornam tabelas. Torna difícil gerar um novo banco de dados e comparar com o banco de dados prod para ver se está sincronizado.
21413 Dave
O Model First não suporta funções SQL definidas pelo usuário (pelo menos no EF4, não sei se isso mudou). Com o Database First, você pode importar UDFs e usá-los em suas consultas LINQ.
Tsahi Asher
Sem diferenças? Tente importar visualizações e tabelas SimpleMembership, gere o banco de dados a partir do modelo e veja o que você obtém. Nem mesmo perto! Isso deve ser de ida e volta, mas o MSFT basicamente abandonou o MF e o DF em vez do CF, o que também é incompleto em termos de uso de visualizações e procs armazenados.
Dave
Você pode desativar o primeiro processo de recreação do banco de dados com base nas migrações de código e fazê-lo manualmente no modelo e no banco de dados. você pode fazer isso especificando disableDatabaseInitialization = "true" em seu web / app.config em <EntityFramework> ..... <contexts> <context type = "myNamespace.mydbContext", "myassemblyORProject" disableDatabaseInitialization = "true" /> </EntityFramework> Você pode excluir a pasta de migrações.
Hasteq
37

Citando as partes relevantes de http://www.itworld.com/development/405005/3-reasons-use-code-first-design-entity-framework

3 razões para usar o primeiro design de código com o Entity Framework

1) Menos crosta, menos inchaço

O uso de um banco de dados existente para gerar um arquivo de modelo .edmx e os modelos de código associados resulta em uma pilha gigante de código gerado automaticamente. Você está implorado para nunca tocar nesses arquivos gerados, para que não quebre algo ou que suas alterações sejam substituídas na próxima geração. O contexto e o inicializador também estão congestionados nessa bagunça. Quando você precisar adicionar funcionalidade aos seus modelos gerados, como uma propriedade somente leitura calculada, precisará estender a classe do modelo. Isso acaba sendo um requisito para quase todos os modelos e você acaba com uma extensão para tudo.

Com o código primeiro, seus modelos codificados manualmente se tornam seu banco de dados. Os arquivos exatos que você está construindo são o que gera o design do banco de dados. Não há arquivos adicionais e não há necessidade de criar uma extensão de classe quando você deseja adicionar propriedades ou qualquer outra coisa que o banco de dados não precise conhecer. Você pode apenas adicioná-los à mesma classe, desde que siga a sintaxe apropriada. Heck, você pode até gerar um arquivo Model.edmx para visualizar seu código, se desejar.

2) Maior controle

Quando você utiliza o DB primeiro, está à mercê do que é gerado para seus modelos para uso em seu aplicativo. Ocasionalmente, a convenção de nomenclatura é indesejável. Às vezes, os relacionamentos e associações não são exatamente o que você deseja. Outras vezes, relacionamentos não transitórios com o carregamento lento causam estragos nas respostas da API.

Embora quase sempre exista uma solução para os problemas de geração de modelo que você possa encontrar, o código inicial fornece um controle completo e refinado desde o início. Você pode controlar todos os aspectos dos modelos de código e do design do banco de dados a partir do conforto do seu objeto de negócios. Você pode especificar com precisão relacionamentos, restrições e associações. Você pode definir simultaneamente os limites de caracteres da propriedade e os tamanhos das colunas do banco de dados. Você pode especificar quais coleções relacionadas devem ser carregadas com antecedência ou não devem ser serializadas. Em resumo, você é responsável por mais coisas, mas está no controle total do design do seu aplicativo.

3) Controle de versão do banco de dados

Este é um grande problema. O controle de versão dos bancos de dados é difícil, mas com as migrações primeiro e primeiro, é muito mais eficaz. Como o esquema do banco de dados é totalmente baseado em seus modelos de código, por versão que controla o código-fonte, você ajuda a versão do banco de dados. Você é responsável por controlar sua inicialização de contexto, o que pode ajudá-lo a executar ações como propagação de dados corporativos fixos. Você também é responsável por criar as primeiras migrações de código.

Quando você habilita as migrações pela primeira vez, uma classe de configuração e uma migração inicial são geradas. A migração inicial é seu esquema atual ou sua linha de base v1.0. A partir desse ponto, você adicionará migrações com timestamp e rotuladas com um descritor para ajudar no pedido de versões. Quando você chama add-migration a partir do gerenciador de pacotes, um novo arquivo de migração será gerado contendo tudo o que foi alterado no seu modelo de código automaticamente nas funções UP () e DOWN (). A função UP aplica as alterações no banco de dados, a função DOWN remove essas mesmas alterações no evento que você deseja reverter. Além disso, você pode editar esses arquivos de migração para adicionar alterações adicionais, como novas visualizações, índices, procedimentos armazenados e qualquer outra coisa. Eles se tornarão um verdadeiro sistema de versão para o seu esquema de banco de dados.

Disse Roohullah Allem
fonte
31

O código primeiro parece ser a estrela em ascensão. Eu dei uma olhada rápida no Ruby on Rails, e o padrão deles é o primeiro do código, com migrações de banco de dados.

Se você estiver criando um aplicativo MVC3, acredito que o Code primeiro tenha as seguintes vantagens:

  • Decoração fácil de atributos - Você pode decorar campos com validação, exigência, etc. atributos, é bastante estranho com a modelagem EF
  • Sem erros de modelagem estranhos - a modelagem EF geralmente apresenta erros estranhos, como quando você tenta renomear uma propriedade de associação, ela precisa corresponder aos metadados subjacentes - muito inflexível.
  • Não é difícil de mesclar - Ao usar ferramentas de controle de versão de código, como mercurial, mesclar arquivos .edmx é um problema. Você é um programador acostumado a C # e aí está mesclando um .edmx. Não é assim com o código primeiro.
  • Compare primeiro com o Code e você terá controle total sem todas as complexidades e incógnitas ocultas para lidar.
  • Eu recomendo que você use a ferramenta de linha de comando do Gerenciador de Pacotes, nem mesmo use as ferramentas gráficas para adicionar um novo controlador às visualizações de andaimes.
  • Migrações de banco de dados - Você também pode ativar as migrações. Isso é tão poderoso. Você faz alterações no seu modelo no código e, em seguida, a estrutura pode acompanhar as alterações no esquema, para implantar atualizações sem problemas, com as versões do esquema atualizadas automaticamente (e rebaixadas, se necessário). (Não tenho certeza, mas isso provavelmente também funciona com o modelo primeiro)

Atualizar

A pergunta também pede uma comparação do code-first com o modelo EDMX / db-first. O Code-first também pode ser usado para essas duas abordagens:

Todd
fonte
3
O Model-first não codifica o POCO primeiro, este é o Code First, Model-First é um Visual Designer para gerar automaticamente POCOs e depois gerar bancos de dados a partir do modelo.
Diego Mendes
Hoje em dia, nas rotas visual e de código, você pode fazer o "Modelo" primeiro ou o "Banco de dados" primeiro. O primeiro é o design manual (através do editor de código ou visual), o segundo é a construção de um banco de dados e a criação do modelo (POCOs ou EDMX).
Todd
11

Eu uso o banco de dados EF primeiro para fornecer mais flexibilidade e controle sobre a configuração do banco de dados.

O código EF primeiro e o modelo pareciam legais inicialmente e fornecem independência de banco de dados; no entanto, ao fazer isso, não permite especificar o que considero informações de configuração de banco de dados muito básicas e comuns. Por exemplo, índices de tabela, metadados de segurança ou possui uma chave primária que contém mais de uma coluna. Acho que quero usar esses e outros recursos comuns do banco de dados e, portanto, tenho que fazer alguma configuração do banco de dados diretamente de qualquer maneira.

Acho que as classes POCO padrão geradas durante o banco de dados primeiro são muito limpas, no entanto, faltam atributos de anotação de dados muito úteis ou mapeamentos para procedimentos armazenados. Eu usei os modelos T4 para superar algumas dessas limitações. Os modelos T4 são impressionantes, especialmente quando combinados com seus próprios metadados e classes parciais.

O modelo primeiro parece ter muito potencial, mas está me dando muitos bugs durante a refatoração de esquema de banco de dados complexo. Não sei por que.

user1618371
fonte
4
Você pode definir chaves compostas usando primeiro o código - stackoverflow.com/questions/5466374/…
Jakub Konecki
3
Para futuros leitores, esse não é mais o caso, você pode adicionar índices, chaves primárias de várias colunas e esse tipo de coisa no EF Code First.
tobiak777
1
EF deveria ter sido fixada de modo a que todos os 3 abordagens poderiam ser usados indistintamente no mesmo banco de dados, pois há vantagens e desvantagens para todos os 3 abordagens
Dave
Além disso, a verdade não é a solução ideal para o primeiro código. Estou usando o banco de dados primeiro por causa da migração para outro IDE / idioma no futuro e quero ter uma estrutura de banco de dados sólida e integrada, outro fato que prefiro primeiro é a flexibilidade de alterar qualquer parte do armazenamento de dados.
QMaster 13/08/16
7

Trabalhar com modelos grandes era muito lento antes do SP1 (não tentei depois do SP1, mas diz-se que é um estalo agora).

Ainda projeto minhas tabelas primeiro e, em seguida, uma ferramenta interna gera os POCOs para mim, portanto, é preciso fazer tarefas repetitivas para cada objeto poco.

Quando você usa sistemas de controle de origem, pode acompanhar facilmente o histórico de seus POCOs, não é tão fácil com o código gerado pelo designer.

Eu tenho uma base para o meu POCO, o que facilita bastante as coisas.

Eu tenho visões para todas as minhas tabelas, cada visão base traz informações básicas para minhas chaves estrangeiras e meus pontos de vista derivam de minhas classes POCO, o que é bastante útil novamente.

E, finalmente, não gosto de designers.

hazimdikenli
fonte
8
'quando você estiver usando sistemas de controle de origem, poderá acompanhar facilmente o histórico de seus POCOs, não é tão fácil com o código gerado pelo designer.' - Eu mantenho o código gerado pelo designer no Controle de origem, para que eu possa sempre visualizar o histórico.
Jakub Konecki
1
@JakubKonecki Você já tentou mesclar arquivos EDMX em uma equipe de mais de 3 pessoas? É apenas uma dor ... Em vez disso, as pessoas tentam evitar a fusão e apenas fazem a outra revisão e repetem suas próprias alterações, porque a fusão é suscetível a falhar em um arquivo gerado automaticamente com milhares de linhas de XML.
usar o seguinte
6

Exemplo de primeira abordagem do banco de dados:

Sem escrever nenhum código: ASP.NET MVC / MVC3 Database Approach First / Database First

E acho que é melhor do que outras abordagens, porque a perda de dados é menor com essa abordagem.

AukI
fonte
Você poderia explicar se há 'menos perda de dados' com a primeira abordagem do DB? Como você executaria a transformação de dados se dividisse a tabela existente em duas?
Jakub Konecki
você provavelmente acabaria escrevendo um script sql que cuida da transformação. Geralmente, a MS anunciou a melhoria da migração de dados do Code First com sua nova versão, portanto isso pode não ser um argumento no futuro.
ckonig
O problema com o banco de dados primeiro é que o design do banco de dados geralmente possui abstrações defeituosas que vazam para o seu modelo ... tabelas de junção, etc. O trabalho do banco de dados é simplesmente persistir no seu modelo.
Nerdfest
Esta "resposta" é uma opinião baseada no seu argumento, sem carne, uma frase não faz uma posição.
TravisO 27/02
Você poderia explicar se há 'menos perda de dados' com a primeira abordagem do DB?
precisa saber é
4

IMHO Acho que todos os modelos têm um ótimo lugar, mas o problema que tenho com a primeira abordagem do modelo está em muitas empresas de grande porte, com os DBAs controlando os bancos de dados. Você não obtém a flexibilidade de criar aplicativos sem usar as primeiras abordagens de banco de dados. Já trabalhei em muitos projetos e, quando se tratava de implantação, eles queriam controle total.

Portanto, por mais que eu concorde com todas as variações possíveis, o Code First, Model First, Database primeiro, você deve considerar o ambiente de produção real. Portanto, se seu sistema for um grande aplicativo de base de usuários, com muitos usuários e DBAs executando o programa, considere a primeira opção do banco de dados apenas minha opinião.

Matthew Parton
fonte
Você está certo. A Microsoft deu aos programadores abordagens diferentes, porque os cenários são diferentes. Você deve saber tudo e decidir, com base em seu cenário, o que é melhor para o projeto e, em seguida, o que você mais gosta.
Sterling Diaz
0

Acho que uma das vantagens do código é que você pode fazer backup de todas as alterações feitas em um sistema de controle de versão como o Git. Como todas as suas tabelas e relacionamentos são armazenados no que são essencialmente apenas classes, você pode voltar no tempo e ver qual era a estrutura do seu banco de dados antes.

anonymous_dojo
fonte