Estou trabalhando com um banco de dados do SQL Server com mais de 1000 tabelas, outras centenas de visualizações e vários milhares de procedimentos armazenados. Esperamos começar a usar o Entity Framework para nossos projetos mais recentes e estamos trabalhando em nossa estratégia para fazê-lo. O que mais me preocupa é a melhor forma de dividir as tabelas em diferentes modelos (EDMX ou DbContext, se for o código primeiro). Eu posso pensar em algumas estratégias logo de cara:
- Dividir por esquema
Temos nossas tabelas divididas em provavelmente uma dúzia de esquemas. Poderíamos fazer um modelo por esquema. Isso não é perfeito, no entanto, porque o dbo ainda acaba sendo muito grande, com mais de 500 tabelas / visualizações. Outro problema é que certas unidades de trabalho acabam tendo que fazer transações que abrangem vários modelos, o que aumenta a complexidade, embora eu assuma que a EF torne isso bastante simples. - Dividir por intenção
Em vez de se preocupar com esquemas, divida os modelos por intenção. Portanto, teremos modelos diferentes para cada aplicativo, projeto, módulo ou tela, dependendo da granularidade que queremos obter. O problema que vejo com isso é que existem certas tabelas que inevitavelmente precisam ser usadas em todos os casos, como User ou AuditHistory. Nós os adicionamos a todos os modelos (viola o DRY, eu acho) ou estão em um modelo separado que é usado por todos os projetos? - Não divida nada - um modelo gigante
Isso é obviamente simples do ponto de vista do desenvolvimento, mas da minha pesquisa e da minha intuição parece que ele pode ter um desempenho terrível, tanto em tempo de design, compilação e possivelmente em tempo de execução.
Qual é a melhor prática para usar o EF em um banco de dados tão grande? Especificamente, quais estratégias as pessoas usam no design de modelos para esse volume de objetos de banco de dados? Existem opções que eu não estou pensando que funcionam melhor do que as que tenho acima?
Além disso, isso é um problema em outras ORMs como o NHibernate? Em caso afirmativo, eles apresentaram soluções melhores que a EF?
fonte
Respostas:
Pessoalmente, tentei criar um esquema enorme para todas as minhas entidades em um projeto relativamente complexo, porém pequeno (~ 300 tabelas). Tínhamos um banco de dados extremamente normalizado (normalização da 5ª forma (digo isso vagamente)) com muitos relacionamentos "muitos para muitos" e extrema imposição de integridade referencial.
Também usamos uma estratégia de "instância única por solicitação", que também não estou convencida de que tenha ajudado.
Ao fazer listagens "definidas explicitamente" simples e razoavelmente simples, pesquisas e salvamentos do desempenho geralmente eram aceitáveis. Mas quando começamos a aprofundar relacionamentos profundos, o desempenho parecia ter caído drasticamente. Comparado a um processo armazenado nesse caso, não houve comparação (é claro). Tenho certeza de que poderíamos ajustar a base de código aqui e ali para melhorar o desempenho, no entanto, neste caso, apenas precisávamos de um aumento de desempenho sem análise devido a restrições de tempo e voltamos ao processo armazenado (ainda o mapeou através da EF, porque a EF forneceu resultados fortemente tipados), precisávamos apenas disso em algumas áreas. Quando tivemos que percorrer todo o banco de dados para criar uma coleção (usando .include () sem par), o desempenho foi notavelmente degradante, mas talvez estivéssemos pedindo demais ..
Portanto, com base na minha experiência, eu recomendaria a criação de um .edmx separado por intenção. Gere apenas o que você usará com base no escopo dessa necessidade. Você pode ter alguns arquivos .edmx com escopo menor para tarefas planejadas e outros grandes, nos quais é necessário atravessar relacionamentos complexos para criar objetos. Eu não tenho certeza de onde está o ponto mágico, mas tenho certeza de que há um ... lol ...
Honestamente, apesar de algumas armadilhas que nós meio que vimos chegando (travessias complexas), o enorme .edmx funcionou bem da perspectiva de "trabalho". Mas você terá que observar a mágica "consertada" que o contexto faz nos bastidores, se você não a desabilitar explicitamente. Além de manter o .edmx sincronizado quando são feitas alterações no banco de dados .. às vezes era mais fácil limpar toda a superfície e recriar as entidades, o que levava 3 minutos, para que não fosse um grande problema.
Isso foi tudo com o EntityFramework 4.1. Eu também estaria realmente interessado em saber sobre sua escolha e experiência final.
E em relação à sua pergunta no nHibernate, na minha opinião, essa é uma questão de lata de minhocas, você latirá nos dois lados da cerca ... Eu ouço muitas pessoas criticando a EF por causa da expulsão sem trabalhar com o desafia e compreende as nuances exclusivas da própria EF. e, embora eu nunca tenha usado o nHibernate na produção, geralmente, se você precisar criar manualmente e explicitamente coisas como mapeamentos, terá um controle mais finito. pode arrastar e soltar, gerar e iniciar CRUD e consulta usando LINQ, eu poderia dar uma porcaria sobre granularidade.
Eu espero que isso ajude.
fonte
Deixe-me começar por um esclarecimento simples: não tenho experiência com um banco de dados tão grande, então o restante da minha resposta não se baseia no exemplo do mundo real.
Então você tem um banco de dados GRANDE e deseja usá-lo com ORM / EF. Eu iria com a segunda escolha. Aqui está minha explicação simples por que:
fonte
Eu diria que você não pode decidir esse tipo de pergunta de uma perspectiva técnica. Eu recomendaria que você construa sua arquitetura com base em seus casos de uso (histórias de usuário etc.). Primeiro encontre seus objetos de negócios. Um objeto de entidade não é por padrão um objeto de negócios. Típico, você terá um objeto de negócios na frente dos objetos da entidade. Em seguida, você pode decidir incrementalmente o que realmente precisa, com base nos requisitos do usuário.
"Um bom arquiteto maximiza o número de decisões não tomadas." Robert C. Martin
http://cleancoder.posterous.com/architecture-deference
fonte
Eu uso uma abordagem híbrida - o material OLTP é tratado pela EF, enquanto operações pesadas, como inserções em lote, atualizações em massa, consultas de relatório etc. são tratadas por Procs armazenados. Isso também facilita o caminho da migração se você não estiver reescrevendo toda a sua camada de dados de uma só vez.
fonte