Diferenças entre NHibernate e Entity Framework

From pontoNETpt June 16, 2012 at 10:35PM

Click here to visit original post!

Introdução

O NHibernate e a Entity Framework são dois duas das frameworks mais populares de O/RM no mundo. NET. Apesar de partilharem algumas funcionalidades, há alguns aspectos em que são completamente diferentes. Este post vai descrever essas diferenças e esperamos ajudar-vos a começar a trabalhar com o que conhecerem pior. Importante realçar, esta é uma seleção pessoal, não é de nenhuma maneira uma lista exaustiva.

História

Primeiro, um pouco de história. O NHibernate é um projeto open-source que foi portado do venerável Hibernate para Java, uma das primeiras frameworks O/RM, mas hoje em dia não está de modo nenhum limitado por este, por exemplo, a versão .NET características específicas, e evoluiu pro diferentes caminhos, da versão Java. A versão actual é a 3.3, com a 3.4 no horizonte. É actualmente baseado em .NET 3.5, mas pode ser usado no. NET 4, apenas não faz uso de qualquer das suas funcionalidades específica. Podem encontrar a sua home page no NHForge .

A Entity Framework 1 saiu com o .NET 3.5 e encontra-se agora na sua segunda versão principal, 4. O Code Firsr assenta nesta mas foi lançado separadamente, e irá também continuar a ser lançado fora de linha com as principais distribuições .NET. Está actualmente na versão 4.3.1 e a versão 5 será lançada junto com o .NET Framework 4.5. Todas as versões terão como alvo a versão actual do .NET, no momento da sua release. A sua home pode ser localizada no MSDN .

Arquitectura

Em NHibernate, há uma separação entre a Unit of Work e a configuração e o modelo de dados. Começamos por criar um objecto Configuration, onde você especificar todas as configurações globais NHibernate como o banco de dados e dialeto de usar, os tamanhos de lotes, os mapeamentos, etc, então você construir umaISessionFactory dele. O ISessionFactory detém modelo e metadados que está ligada a um determinado banco de dados e as configurações que vieram do objeto deconfiguração, e, normalmente haverá apenas uma instância de cada um em um processo.Finalmente, você criar instâncias de ISession do ISessionFactory, que é a representação NHibernate da Unidade de Trabalho e Mapa de Identidade . Este é um objeto leve, basicamente abre e fecha uma conexão de dados, conforme necessário e mantém o controle das entidades associados. Objetos ISession são baratas para criar e dispor, pois toda a complexidade do modelo é armazenado no ISessionFactory e objetos de configuração.

Quanto à Entity Framework, o ObjectContext / DbContext mantém a configuração do modelo, e age como a unidade de trabalho, mantendo referências a todas as instâncias entidade conhecida. Esta classe não é, portanto, leve como a sua homóloga no NHibernate e não é raro ver exemplos em que uma instância é armazenada em cache num campo.

Mapeamentos

Tanto o NHibernate como a Entity Framework (Code First) suportam a utilização de POCOs para representar entidades, não são necessárias classes base (nem sequer são possíveis, no caso do NHibernate).

Quanto aos mapeamentos de e para a base de dados, o NHibernate suporta três tipos:

  • Baseado em XML, que têm a vantagem de não amarrar a classe a um O/RM particular; os ficheiros XML podem ser incluídos como ficheiros no file system ou como recursos embebidos numa assembly;
  • Por atributos, para manter tanto a entidade como os seus mapeamentos no mesmo sítio com o custom de “poluir” a classe com atributos específicos do NHibernate;
  • Com base em código fortemente tipado, que permite a criação dinâmica do modelo e torná-lo fortemente tipado, de modo que, por exemplo, se uma propriedade mudar de nome, o mapeamento também é alterado, pelo Visual Studio.

A Entity Framework pode usar:

  • Atributos (ainda que os atributos não permitam exprimir todas as possibilidades – por exemplo, cascatas);
  • Fortemente tipados por código.

Bases de Dados Suportadas

Com o NHibernate podemos aceder a quase qualquer base de dados, incluindo:

  • SQL Server;
  • SQL Server Compact;
  • SQL Server Azure;
  • Oracle;
  • DB2;
  • PostgreSQL;
  • MySQL;
  • Sybase Adaptive Server/SQL Anywhere;
  • Firebird;
  • SQLLite;
  • Informix;
  • Qualquer uma através de OLE DB;
  • Qualquer uma através de ODBC.

Por omissão, o Entity Framework apenas suporta SQL Server, mas existem uma série de fornecedores, tanto livres como comerciais, para algumas das bases de dados mais usadas, como Oracle e MySQL. Vejam a lista aqui.

Estratégias de Herança

Tanto o NHibernate como a Entity Framework suportam as três estratégias de mapeamento canónicas: Table Per Type Hierarchy (Single Table Inheritance), Table Per Type (Class Table Inheritance) e Table Per Concrete Type (Concrete Table Inheritance).

Associações

Relativamente a associações, ambos suportam um para um, um para muitos e muitos para muitos. No entanto, o NHibernate oferece muito mais tipos de colecções:

  • “Sacos” (bags) de entidades ou valores: não ordenados, possívelmente com duplicados;
  • Listas de valores ou entitdades: ordenados, indexados por uma coluna numérica;
  • Mapas de entidades ou valores: indexados ou por uma entidade ou por um valor;
  • Conjuntos (sets): não ordenados, sem duplicados;
  • Arrays de entidades ou valores: indexados, imutáveis.

Consultas

O NHibernate expôe vários APIs:

  • LINQ será provavelmente o mais usado actualmente, e verdadeiramente não precisa de apresentação;
  • O Hibernate Query Language (HQL) é uma linguagem semelhante ao SQL, orientada a objectos e independente da base de dados que existe desde a criação do NHibernate e que ainda oferece as possibilidades mais avançadas; bem adaptado a queries dinâmicas, ainda que usando concatenação de strings;
  • O Criteria API é uma implementação do padrão Query Object onde criamos uma representação conceptual semi-abstracta da query a executar por meio de um modelo de classes; também uma boa escolha para queries dinâmicas;
  • O Query Over oferece um API semelhante ao Criteria, mas usando expressões LINQ em vez de strings; por isso, ainda que mais amigo de refactoring do que o Criteria, também é menos apropriado para queries dinâmicas;
  • SQL, incluindo stored procedures, também pode ser usado;
  • Existe integração com o indexador Lucene.NET.

Já a Entity Framework:

  • O LINQ to Entities é plenamente suportado, e a sua implementação é considerada muito completa; é o API de escolha da maior parte dos programadores;
  • Entity-SQL, o duplicado do HQL, também é uma linguagem orientada a objectos e independente da base de dados, que pode ser usada para queries dinâmicas;
  • SQL, claro está, também é suportado.

Caching

Tanto o NHibernate como a Entity Framework, claro está, possuem cache de primeiro nível nas suas implementações de Unit of Work. O NHibernate também possui uma cache de segundo nível, que pode ser usada entre várias ISessionFactorys, mesmo em diferentes processos/máquinas:

De raíz, a Entity Framework não possui nenhum mecanismo de cache de segundo nível, no entanto, existem alguns exemplos que mostram como podemos adicionar um.

Geradores de IDs

O NHibernate suporta várias estratégias de geração de IDs, apoiadas na base de dados e não:

  • Identidades (para o SQL Server, MySQL, e outras bases de dados que suportam colunas identidade);
  • Sequências (para o Oracle, PostgreSQL, e outras que suportam sequências);
  • Baseado em triggers;
  • HiLo;
  • HiLo com sequências (em bases de dados que suportam sequências);
  • Vários formatos de GUID, tanto em formato GUID propriamente dito como em formato de string;
  • Incremental (para cenários de apenas um utilizador simultâneo);
  • Atribuído (convém saber o que se está a fazer);
  • Estilo de sequência (ou usa uma sequência real ou uma coluna de uma tabela);
  • Tabela de identificadores;
  • Pooled (similar to HiLo but stores high values in a table);
  • Nativo (usa o mecanismo suportado pela base de dados actual, identidades ou sequências).

A Entity Framework apenas suporta:

  • Identidades;
  • GUIDs;
  • Valores atribuídos.

Propriedades

O NHibernate oferece suporte a propriedades de tipos de entidades (um para um ou muitos para um), coleções (um para muitos ou muitos para muitos), bem como escalares e enumerações. Oferece um mecanismo para ter tipos de propriedade complexos gerados a partir da base de dados, que ainda incluem suporte para a consulta. Também oferece suporte a propriedades originadas a partir de fórmulas SQL.

A Entity Framework suporta apenas escalares, tipos de entidade e coleções. Enumerações apoio virá na próxima versão.

Eventos e Intercepção

O NHibernate tem um modelo de eventos muito rico, que expõe mais de 20 eventos, quer para execução síncrona ou assíncrona pré-pós-execução, incluindo:

  • Pre/Pós-Carregamento;
  • Pre/Pós-Apagamento;
  • Pre/Pós-Inserção;
  • Pre/Pós-Actualização;
  • Pre/Pós-Flush.

Também possui intercepção de instanciação de classes e geração de SQL..

Quanto ao Entity Framework, existem apenas dois eventos:

  • ObjectMaterialized (depois de carregar uma entidade da base de dados);
  • SavingChanges (antes de guardar as alterações, que incluem apagar, inserir e actualizar).

Detectar Alterações

Para o NHibernate, bem como para a Entity Framework, todas as alterações são controladas pela sua respectiva Unit of Work.As entidades podem ser associadas ou destacadas desta, a Entity Framework, adicionalmente, também suporta auto-tracking entities.

Controle de Concorrência Optimístico

O NHibernate suporta todos os cenários imagináveis:

  • ROWVERSION do SQL Server;
  • ORA_ROWSCN do Oracle;
  • Uma coluna contendo data e hora;
  • Uma coluna contendo um número de versão;
  • Todas/Apenas propriedades com valores modificados.

A Entity Framework é mais focado na Entity Framework, por isso só suporta:

  • ROWVERSION do SQL Server;
  • Comparar todas / algumas colunas.

Processamento em Batch

NHibernate tem suporte completo para processamento em batch, mas apenas se o gerador de IDs em uso não for baseado na base de dados (por exemplo, não pode ser usado com Identity), ao passo que a Entity Framework não tem nenhum suporte.

Cascata

Ambos suportam cascatas para colecções e associações: quando uma entidade é apagada, os seus filhos conceituais também são apagados. O NHibernate também oferece a possibilidade de colocar a coluna da chave estrangeira sobre as crianças a NULL em vez de remover a entidade filha.

Efectuar Alterações

O objecto ISession do NHibernate tem uma propriedade FlushMode que pode ter os seguintes valores:

  • Auto: as alterações são enviadas para a base de dados quando necessário, por exemplo, se há entidades modificadas, e uma consulta é realizada contra este tipo de entidade, ou se o objecto ISession está a ser disposed;
  • Commit: as alterações são enviadas ao fazer commit da transaçcão actual;
  • Never: as alterações só são enviadas quando for explicitamente chamado o Flush().

Quanto à Entity Framework, as alterações têm de ser explicitamente enviadas através de uma chamada a AcceptAllChanges()/SaveChanges().

Lazy Loading

O NHibernate suporta lazy loading para:

  • Entidades associadas, um a um, muitos para um);
  • Colecções (um para muitos, muitos para muitos);
  • Propriedades escalares (BLOBs ou CLOBs ).

A Entity Framework apenas suporta lazy loading para:

  • Entidades associadas;
  • Colecções.

Gerar e Actualizar a Base de Dados

Tanto o NHibernate e Entity Framework Código First (com a API Migrações ) permitem criar o modelo da base de dados a partir do mapeamento e actualizá-lo se houver alterações neste.

Extensibilidade

Como você pode adivinhar, o NHibernate é muito mais extensível que a Entity Framework.Basicamente, tudo pode ser personalizado, desde a geração de IDs, até a transformação de LINQ para SQL, suporte de SQL nativo em HQL, tipos de coluna personalizadas, colecções personalizadas, geração de SQL, bases de dados suportadas, etc Com a Entity Framework as opções são mais limitadas, pelo menos, porque praticamente não existe informação quanto ao que pode ser substituído / alterado. Existe sim um modelo de providers que pode ser estendido para suportar qualquer base de dados.

Integração Com Outros APIs e Ferramentas Microsoft

Quando se trata de integração com tecnologias da Microsoft, não será nenhuma surpresa que a Entity Framework oferece o melhor suporte. Por exemplo, as seguintes tecnologias são totalmente suportadas:

Documentação

Este é outro ponto onde a Entity Framework é superior: NHibernate não tem, para começar, o seu API sincronizado com a versão actual. Existe uma lista de discussão da comunidade, blogs e wikis, embora estes últimos não sejam muito usados. O Entity Framework tem um número imenso de recursos no MSDN e, é claro, vários fóruns e grupos de discussão.

Conclusão

Como eu disse, esta é uma lista pessoal. Pode ser uma surpresa para alguns que Entity Framework está tão atrás em relação ao NHibernate em tantos aspectos, mas é verdade que o NHibernate é muito mais antigo e, devido à sua natureza de código aberto, não está vinculado a prazos específicos de produtos específicos e pode, portanto, evoluir muito mais rapidamente.Eu gosto de ambos, e escolho o que é melhor para o trabalho que tenho em mãos. Estou ansioso para ver as mudanças na EF5 que vão acrescentar um valor significativo para um produto já interessante.

Então, o que acham? Será que eu esquecer alguma coisa importante ou há alguma coisa que vale a pena falar? Aguardo os vossos comentários!

2 comments

  1. Um artigo muito interessante e que pode ajudar muito na hora de decidir qual usar em qual situação.

    Muito obrigado.

  2. Exelente artigo, exlareceu bastantes dúvidas a respeito dos dois principais ORM que conheço, já tinha trabalhado com o nHibernate, mas agora ( por normas da empresa; contrato) vou ter que utilizar o Entity, estou com uma espectativa boa. Espero que a Microsoft continue melhorando as ferramentas para desenvolvimento (principalmente MVC!).

    Shalom.

Leave a Reply

Your email address will not be published. Required fields are marked *