Anúncios

Mapeando heranças no Entity Framework Code First

O Entity Framework Code First provê suporte ao mapeamento de heranças. Podemos fazer este mapeamento de duas maneiras, via Table Per Hierarchy ou Table Per Type. Vamos ver seu funcionamento e suas diferenças neste post.

Para os exemplos desta publicação utilizaremos a mesma estrutura de classes para os dois modelos de mapeamento. A estrutura proposta engloba três classes: Veiculo, Carro e Aviao. Nessa estrutura as classes Carro e Aviao herdam de Veiculo. O diagrama deste modelo pode ser visto na figura abaixo:

diagramaClasses

O código necessário para criação destas classes é bastante simples e pode ser conferido logo abaixo:

codigoEntidades

Podemos notar que as classes Carro e Aviao herdam de Veiculo e adicionam algumas propriedades próprias, que fazem parte do seu domínio.

Após criadas as entidades vamos criar nosso DataContext, objeto que funcionará como ponte entre a nossa aplicação e o nosso banco de dados. Para criação do DataContext utilizaremos o bloco abaixo, ele possui todos os recursos necessários para começarmos a trabalhar com o mapeamento de heranças do Entity Framework Code First.

dataContext

Podemos ver que este DataContext possui algumas configurações interessantes, sendo elas:
– Utilização do inicializador DropCreateDataBaseAlways: como estamos demonstrando um exemplo que irá afetar a estrutura do banco de dados, vamos utilizar um inicializador que irá apagar e reconstruir o banco de dados toda vez que executarmos a aplicação. Este inicializador é favorável quando estamos fazendo testes desse tipo, para ambientes de produção seu uso não é indicado.
– Remoção da convenção PluralizingTableNameConvention: para evitarmos a criação de tabelas com nomenclaturas do EF Code First.

E para realizarmos os testes em nossa base de dados utilizaremos um bloco de código que fará inclusões na tabela Veiculos, e então observaremos o comportamento do Entity Framework Code First ao mapear as entidades e criar o banco de dados. O bloco que utilizaremos para fazer as inclusões é o seguinte:

program

Pronto, agora falaremos mais específicamente sobre o mapeamento do Entity Framework Code First…

Table Per Hierarchy

Table Per Hierarchy (TPH) descreve o mapeamento de heranças para uma única tabela que utiliza uma coluna para descriminar um subtipo de outro. Quando criamos uma herança no modelo por padrão será utilizada esta convenção. Isto é, toda a estrutura de heranças será mapeada para uma única tabela, onde será criado um campo para diferenciar um tipo do outro. Se executarmos nosso bloco de código de teste nossa base de dados será criada e ficará deste modo:

table1

Note que todas as propriedades de todas as classes pertencentes a esta hierárquia foram criadas na mesma tabela e que uma coluna chamada “Discriminator” foi criada. Essa coluna é utilizada para diferenciar um tipo de dados do outro. Se observarmos os dados que foram salvos na base de dados iremos entender essa diferença, veja a figura abaixo:

dados

Agora podemos ver que o mapeamento Table Per Hierarchy criou uma única tabela e que utiliza uma coluna para diferenciar os dados de um tipo dos dados do outro tipo de dados.

Table Per Type

Table Per Type (TPT), como o próprio nome já diz, irá criar uma tabela para cada tipo de dados, com uma Foreign Key fazendo relacionamento com a tabela mapeada para a classe base. Para utilizarmos este mapeamento devemos fazer uma modificação na nossa classe DataContext, registrando o mapeamento do modelo como TPT. A classe DataContext deve ficar como:

novoDataContext

Veja que a única modificação que fizémos foi explicitamente mapear as classes Carro e Aviao para suas respectivas tabelas. Depois de executarmos a aplicação, veremos que cada classe agora possui sua respectiva tabela, como na figura abaixo:

table02

E se olharmos os dados no banco de dados, eles estão assim:

dados02

Veja que os dados das tabelas filhas estão ligados aos dados da tabela pai através da coluna Id. Este é o elo de ligação entre as entidades na estrutura de herança.

Por
Fernando Henrique Inocêncio Borba Ferreira
Microsoft Most Valuable Professional – Data Platform Development

Anúncios

15 Responses to Mapeando heranças no Entity Framework Code First

  1. Seu artigo facilitou muito a minha vida! Parabéns pelo artigo e obrigado!

  2. Deyvidy says:

    Ajudou muito mesmo. Obrigado.

  3. Rodrigo says:

    Caraca…eu já estava desistindo de utilizar o Entity, mas agora vou me aprofundar mais nesse ORM.

  4. MAtheus says:

    Bacana, bem esclarecedor. Parabéns!

  5. Pingback: Trabalhando com Herança no Entity Framework

  6. Prezado Fernando
    Parabéns pelo post, claro, simples e objetivo.

  7. Pingback: Trabalhando com os três tipos de herança no Entity Framework | iMasters

  8. Claudio says:

    Excelente post!
    Seu blog virou uma referencia para mim!
    Muito obrigado

  9. Leandro Saint says:

    Muito bom o artigo! Obrigado hermano!

  10. Rodrigo says:

    Qual das duas obteve maior performance? 🙂

    • Olá Rodrigo,

      A questão do “ganho ou perda” de performance neste caso está mais próximo a estrutura de seu banco de dados.

      Do lado do .NET Framework isso é transparente, mas para o banco de dados, o número de colunas, complexidade das chaves, tipos de indíces e o particionamento de tabelas podem pesar de maneira diferente.

      Acredito que, vale a pena conversar com o DBA de seu projeto, e/ou fazer testes com as diferentes abordagens.

      []s!

  11. Allan Camilato says:

    Fernando, e para trazer uma lista de Veículos trazendo os dados das tabelas filhas como faço? geralmente eu faço um .Include, porém no exemplo não existe um DbSet para Carro e Avião, eu poderia criar um para cada entidade filha?

  12. alisson beluci beloti says:

    Vamos lá, veja se pode me ajudar… Eu tenho os objestos Fornecedor, Vendedor, Cliente e outros que Herdam de Pessoa. Seria possível utilizar uma tabela só para todos, ou seja, opção condicional no mapeamento para essa mesma tabela e com algum campo que os diferencie. exemplo Tipo?

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: