Herança de TPH do Designer
Esse passo a passo mostra como implementar a herança TPH (tabela por hierarquia) em seu modelo conceitual com o Designer do Entity Framework (EF Designer). A herança de TPH usa uma tabela de banco de dados para manter dados para todos os tipos de entidade em uma hierarquia de herança.
Neste passo a passo, mapearemos a tabela Pessoa para três tipos de entidade: Pessoa (o tipo base), Aluno (deriva de Pessoa) e Instrutor (deriva de Pessoa). Criaremos um modelo conceitual a partir do banco de dados (Database First) e, em seguida, alteraremos o modelo para implementar a herança TPH usando o EF Designer.
É possível mapear para uma herança TPH usando o Model First, mas você teria que escrever seu próprio fluxo de trabalho de geração de banco de dados, o que é complexo. Em seguida, você atribuiria esse fluxo de trabalho à propriedade Database Generation Workflow no EF Designer. Uma alternativa mais fácil é usar o Code First.
Outras opções de herança
TPT (tabela por tipo) é outro tipo de herança em que tabelas separadas no banco de dados são mapeadas para entidades que participam da herança. Para obter informações sobre como mapear a herança tabela por tipo com o EF Designer, consulte Herança TPT do EF Designer.
Os modelos de herança de tipo tabela por concreto (TPC) e herança mista têm suporte no runtime do Entity Framework, mas não são compatíveis com o EF Designer. Se você quiser usar TPC ou herança mista, você tem duas opções: usar Code First ou editar manualmente o arquivo EDMX. Se você optar por trabalhar com o arquivo EDMX, a janela Detalhes do mapeamento será colocada em "modo de segurança" e você não poderá usar o designer para alterar os mapeamentos.
Pré-requisitos
Para concluir esta explicação passo a passo, será necessário:
- Uma versão recente do Visual Studio.
- O banco de dados do exemplo escolar.
Configurar o Projeto
- Open Visual Studio 2012.
- Selecione Arquivo-> Novo -> Projeto
- No painel esquerdo, clique em Visual C# e, em seguida, selecione o modelo Console.
- Digite TPHDBFirstSample como o nome.
- Selecione OK.
Criar um modelo
- Clique com o botão direito do mouse no nome do projeto no Gerenciador de Soluções e selecione Adicionar -> Novo Item.
- Selecione Dados no menu à esquerda e selecione Modelo de Dados de Entidade ADO.NET no painel Modelos.
- Insira TPHModel.edmx para o nome do arquivo e clique em Adicionar.
- Na caixa de diálogo Escolher Conteúdos do Modelo, selecione Gerar do banco de dados e, em seguida, clique em Próximo.
- Clique em Nova Conexão. Na caixa de diálogo Propriedades da Conexão, insira o nome do servidor (por exemplo, (localdb)\mssqllocaldb), selecione o método de autenticação, digite Escolar como o nome do banco de dados e clique em OK. A caixa de diálogo Escolher suas Conexões de Dados é atualizada com suas configurações de conexões de banco de dados.
- Na caixa de diálogo Escolher objetos de banco de sados, no nó Tabelas, selecione a tabela Person.
- Clique em Concluir.
O Designer do Entity, que fornece uma superfície de design para editar seu modelo, é exibido. Todos os objetos selecionados na caixa de diálogo Escolher seus Objetos de Banco de Dados são adicionados ao modelo.
É assim que a tabela Person fica no banco de dados.
Implementar a herança de tabela por hierarquia
A tabela Person tem a coluna discriminatória, que pode ter um dos dois valores: “Student” e “Instructor”. Dependendo do valor, a tabela Person será mapeada para a entidade Student ou para a entidade Instructor. A tabela Person também tem duas colunas, HireDate e EnrollmentDate, que devem ser anuláveis porque uma pessoa não pode ser aluno e instrutor ao mesmo tempo (pelo menos não neste passo a passo).
Adicionar novas entidades
- Adicionar uma nova entidade. Para fazer isso, clique com o botão direito do mouse em um espaço vazio da superfície de design do Designer do Entity Framework e selecione Adicionar>Entidade.
- Digite Instructor para o nome da entidade e selecione Person na lista suspensa para o tipo Base.
- Clique em OK.
- Adicione outra nova entidade. Digite Student para o nome da entidade e selecione Person na lista suspensa para o tipo Base.
Dois novos tipos de entidade foram adicionados à superfície de design. Uma seta aponta dos novos tipos de entidade para o tipo de entidade Person. Isso indica que Person é o tipo base para os novos tipos de entidade.
- Clique com o botão direito do mouse na propriedade HireDate da entidade Person. Selecione Recortar (ou use a tecla Ctrl-X).
- Clique com o botão direito do mouse na entidade Instructor e selecione Colar (ou use a tecla Ctrl-V).
- Clique com o botão direito do mouse na propriedade HireDate e selecione Propriedades.
- Na janela Propriedades, defina a propriedade Nullable como false.
- Clique com o botão direito do mouse na propriedade EnrollmentDate da entidade Person. Selecione Recortar (ou use a tecla Ctrl-X).
- Clique com o botão direito do mouse na entidade Student e selecione Colar(ou usar a tecla Ctrl-V).
- Selecione a propriedade EnrollmentDate e defina a propriedade Nullable como false.
- Selecione o tipo de entidade Person. Na janela Propriedades, defina sua propriedade Abstract como true.
- Exclua a propriedade discriminatória de Person. O motivo pelo qual ela deve ser excluída é explicado na seção a seguir.
Mapear as entidades
Clique com o botão direito do mouse em Instructor e selecione Mapeamento de Tabela. A entidade Instructor está selecionada na janela Detalhes do Mapeamento.
Clique <em Adicionar uma Tabela ou Exibição> na janela Detalhes do Mapeamento. O campo <Adicionar uma Tabela ou Exibição> torna-se uma lista suspensa de tabelas ou exibições para as quais a entidade selecionada pode ser mapeada.
Selecione Person na lista suspensa.
A janela Detalhes do Mapeamento é atualizada com mapeamentos de coluna padrão e uma opção para adicionar uma condição.
Clique em <Adicionar uma Condição>. O campo <Adicionar uma Condição> torna-se uma lista suspensa de colunas para as quais as condições podem ser definidas.
Selecione discriminatória na lista suspensa.
Na coluna Operator da janela Detalhes do Mapeamento, selecione = na lista suspensa.
Na coluna Valor/Propriedade, digite Instructor. O resultado final deve ter essa aparência:
Repita estas etapas para o tipo de entidade Student, mas torne a condição igual ao valor Student.
O motivo pelo qual queríamos remover a propriedade discriminatória é porque você não pode mapear uma coluna de tabela mais de uma vez. Essa coluna será usada para mapeamento condicional, portanto, ela também não pode ser usada para mapeamento de propriedades. A única maneira de usá-la para ambos, se uma condição usar uma comparação Is Null ou Is Not Null.
A herança tabela por hierarquia agora é implementada.
Use o modelo
Abra o arquivo Program.cs onde o método Main está definido. Cole o código a seguir na função Main. O código executa três consultas. A primeira consulta traz de volta todos os objetos Person. A segunda consulta usa o método OfType para retornar objetos Instructor. A terceira consulta usa o método OfType para retornar objetos Student.
using (var context = new SchoolEntities())
{
Console.WriteLine("All people:");
foreach (var person in context.People)
{
Console.WriteLine(" {0} {1}", person.FirstName, person.LastName);
}
Console.WriteLine("Instructors only: ");
foreach (var person in context.People.OfType<Instructor>())
{
Console.WriteLine(" {0} {1}", person.FirstName, person.LastName);
}
Console.WriteLine("Students only: ");
foreach (var person in context.People.OfType<Student>())
{
Console.WriteLine(" {0} {1}", person.FirstName, person.LastName);
}
}