Partilhar via


Introdução com o Entity Framework 4.0 Database First e o ASP.NET 4 Web Forms – Parte 6

por Tom Dykstra

O aplicativo Web de exemplo da Contoso University demonstra como criar aplicativos ASP.NET Web Forms usando o Entity Framework 4.0 e o Visual Studio 2010. Para obter informações sobre a série de tutoriais, consulte o primeiro tutorial da série

Implementando herança de tabela por hierarquia

No tutorial anterior, você trabalhou com dados relacionados adicionando e excluindo relações e adicionando uma nova entidade que tinha uma relação com uma entidade existente. Este tutorial mostrará como implementar a herança no modelo de dados.

Na programação orientada a objetos, você pode usar a herança para facilitar o trabalho com classes relacionadas. Por exemplo, você pode criar Instructor classes e Student que derivam de uma Person classe base. Você pode criar os mesmos tipos de estruturas de herança entre entidades no Entity Framework.

Nesta parte do tutorial, você não criará novas páginas da Web. Em vez disso, você adicionará entidades derivadas ao modelo de dados e modificará as páginas existentes para usar as novas entidades.

Herança de tabela por hierarquia versus tabela por tipo

Um banco de dados pode armazenar informações sobre objetos relacionados em uma tabela ou em várias tabelas. Por exemplo, no School banco de dados, a Person tabela inclui informações sobre alunos e instrutores em uma única tabela. Algumas das colunas se aplicam somente a instrutores (HireDate), algumas somente aos alunos (EnrollmentDate) e outras a ambos (LastName, FirstName).

image11

Você pode configurar o Entity Framework para criar Instructor entidades e Student herdadas da Person entidade. Esse padrão de geração de uma estrutura de herança de entidade de uma única tabela de banco de dados é chamado de herança de tabela por hierarquia (TPH).

Para cursos, o School banco de dados usa um padrão diferente. Cursos online e cursos no local são armazenados em tabelas separadas, cada uma com uma chave estrangeira que aponta para a Course tabela. As informações comuns a ambos os tipos de curso são armazenadas apenas na Course tabela.

image12

Você pode configurar o modelo de dados do Entity Framework para que OnlineCourse as entidades e OnsiteCourse herdem da Course entidade. Esse padrão de geração de uma estrutura de herança de entidade de tabelas separadas para cada tipo, com cada tabela separada fazendo referência a uma tabela que armazena dados comuns a todos os tipos, é chamado de herança de tabela por tipo (TPT).

Os padrões de herança de TPH geralmente oferecem melhor desempenho no Entity Framework do que os padrões de herança TPT, pois os padrões TPT podem resultar em consultas de junção complexas. Este passo a passo demonstra como implementar a herança de TPH. Você fará isso executando as seguintes etapas:

  • Criar Instructor e Student tipos de entidade que derivam de Person.
  • Mova as propriedades que pertencem às entidades derivadas da Person entidade para as entidades derivadas.
  • Defina restrições em propriedades nos tipos derivados.
  • Torne a Person entidade uma entidade abstrata.
  • Mapeie cada entidade derivada para a Person tabela com uma condição que especifica como determinar se uma Person linha representa esse tipo derivado.

Adicionando entidades de instrutor e aluno

Abra o arquivo SchoolModel.edmx , clique com o botão direito do mouse em uma área desocupada no designer, selecione Adicionar e, em seguida, selecione Entidade.

image01

Na caixa de diálogo Adicionar Entidade , nomeie a entidade Instructor e defina sua opção Tipo base como Person.

image02

Clique em OK. O designer cria uma Instructor entidade derivada da Person entidade . A nova entidade ainda não tem nenhuma propriedade.

image03

Repita o procedimento para criar uma Student entidade que também deriva de Person.

Somente instrutores têm datas de contratação, portanto, você precisa mover essa propriedade da Person entidade para a Instructor entidade. Na entidade , clique com o Person botão direito do mouse na HireDate propriedade e clique em Recortar. Em seguida, clique com o botão direito do mouse em Propriedades na Instructor entidade e clique em Colar.

image04

A data de contratação de uma Instructor entidade não pode ser nula. Clique com o botão direito do mouse na HireDate propriedade, clique em Propriedades e, na janela Propriedades , altere Nullable para False.

image05

Repita o procedimento para mover a EnrollmentDate propriedade da Person entidade para a Student entidade. Verifique se você também definiu Nullable como False para a EnrollmentDate propriedade .

Agora que uma Person entidade tem apenas as propriedades comuns às Instructor entidades e Student (além das propriedades de navegação, que você não está movendo), a entidade só pode ser usada como uma entidade base na estrutura de herança. Portanto, você precisa garantir que ela nunca seja tratada como uma entidade independente. Clique com o botão direito do mouse na Person entidade, selecione Propriedades e, na janela Propriedades , altere o valor da propriedade Abstract para True.

image06

Mapeando entidades de instrutor e aluno para a tabela Person

Agora você precisa informar ao Entity Framework como diferenciar entre Instructor as entidades e Student no banco de dados.

Clique com o botão direito do mouse na Instructor entidade e selecione Mapeamento de Tabela. Na janela Detalhes do Mapeamento , clique em Adicionar uma Tabela ou Exibição e selecione Pessoa.

image07

Clique em Adicionar uma Condição e selecione HireDate.

image09

Altere Operator para Is e Value/Property para Not Null.

image10

Repita o procedimento para a Students entidade, especificando que essa entidade é mapeada para a Person tabela quando a EnrollmentDate coluna não é nula. Em seguida, salve e feche o modelo de dados.

Compile o projeto para criar as novas entidades como classes e disponibilizá-las no designer.

Usando as entidades de instrutor e aluno

Quando você criou as páginas da Web que trabalham com dados de alunos e instrutores, você as Person vincula ao conjunto de entidades e filtra na HireDate propriedade ou EnrollmentDate para restringir os dados retornados aos alunos ou instrutores. No entanto, agora, quando você associa cada controle de fonte de dados ao Person conjunto de entidades, pode especificar que somente Student os tipos de entidade ou Instructor devem ser selecionados. Como o Entity Framework sabe como diferenciar alunos e instrutores no Person conjunto de entidades, você pode remover as Where configurações de propriedade inseridas manualmente para fazer isso.

No Visual Studio Designer, você pode especificar o tipo de entidade que um EntityDataSource controle deve selecionar na caixa suspensa EntityTypeFilter do Configure Data Source assistente, conforme mostrado no exemplo a seguir.

image13

E, na janela Propriedades , você pode remover Where valores de cláusula que não são mais necessários, conforme mostrado no exemplo a seguir.

image14

No entanto, como você alterou a marcação de controles para EntityDataSource usar o ContextTypeName atributo , não é possível executar o assistente Configurar Fonte de Dados em EntityDataSource controles que você já criou. Portanto, você fará as alterações necessárias alterando a marcação.

Abra a página Students.aspx . StudentsEntityDataSource No controle , remova o Where atributo e adicione um EntityTypeFilter="Student" atributo . A marcação agora será semelhante ao seguinte exemplo:

<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
        EntitySetName="People" EntityTypeFilter="Student"
        Include="StudentGrades"
        EnableDelete="True" EnableUpdate="True" 
        OrderBy="it.LastName" >
    </asp:EntityDataSource>

Definir o EntityTypeFilter atributo garante que o EntityDataSource controle selecione apenas o tipo de entidade especificado. Se você quisesse recuperar os Student tipos de entidade e Instructor , não definiria esse atributo. (Você tem a opção de recuperar vários tipos de entidade com um EntityDataSource controle somente se estiver usando o controle para acesso a dados somente leitura. Se você estiver usando um EntityDataSource controle para inserir, atualizar ou excluir entidades e se o conjunto de entidades ao qual ele está associado puder conter vários tipos, você só poderá trabalhar com um tipo de entidade e terá que definir esse atributo.)

Repita o procedimento para o SearchEntityDataSource controle, exceto remover apenas a parte do Where atributo que seleciona entidades Student em vez de remover a propriedade completamente. A marca de abertura do controle agora será semelhante ao seguinte exemplo:

<asp:EntityDataSource ID="SearchEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
        EntitySetName="People" EntityTypeFilter="Student"
        Where="it.FirstMidName Like '%' + @StudentName + '%' or it.LastName Like '%' + @StudentName + '%'" >

Execute a página para verificar se ela ainda funciona como antes.

image15

Atualize as seguintes páginas que você criou em tutoriais anteriores para que elas usem as entidades e Instructor novas Student em vez de Person entidades e, em seguida, execute-as para verificar se elas funcionam como antes:

  • Em StudentsAdd.aspx, adicione EntityTypeFilter="Student" ao StudentsEntityDataSource controle . A marcação agora será semelhante ao seguinte exemplo:

    <asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
            EntitySetName="People" EntityTypeFilter="Student"
            EnableInsert="True" 
        </asp:EntityDataSource>
    

    image16

  • Em About.aspx, adicione EntityTypeFilter="Student" ao StudentStatisticsEntityDataSource controle e remova Where="it.EnrollmentDate is not null". A marcação agora será semelhante ao seguinte exemplo:

    <asp:EntityDataSource ID="StudentStatisticsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
            EntitySetName="People" EntityTypeFilter="Student"
            Select="it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents"
            OrderBy="it.EnrollmentDate" GroupBy="it.EnrollmentDate" >
        </asp:EntityDataSource>
    

    image17

  • Em Instructors.aspx e InstructorsCourses.aspx, adicione EntityTypeFilter="Instructor" ao InstructorsEntityDataSource controle e remova Where="it.HireDate is not null". A marcação em Instructors.aspx agora se assemelha ao seguinte exemplo:

    <asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" 
                ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false"
                EntitySetName="People" EntityTypeFilter="Instructor" 
                Include="OfficeAssignment" 
                EnableUpdate="True">
            </asp:EntityDataSource>
    

    image18

    A marcação em InstructorsCourses.aspx agora será semelhante ao seguinte exemplo:

    <asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
            EntitySetName="People" EntityTypeFilter="Instructor" 
            Select="it.LastName + ',' + it.FirstMidName AS Name, it.PersonID">
        </asp:EntityDataSource>
    

    image19

Como resultado dessas alterações, você melhorou a manutenção do aplicativo da Contoso University de várias maneiras. Você moveu a lógica de seleção e validação para fora da camada de interface do usuário (marcação.aspx ) e a tornou parte integrante da camada de acesso a dados. Isso ajuda a isolar o código do aplicativo de alterações que você pode fazer no futuro para o esquema de banco de dados ou o modelo de dados. Por exemplo, você pode decidir que os alunos podem ser contratados como auxiliares dos professores e, portanto, obteriam uma data de contratação. Em seguida, você pode adicionar uma nova propriedade para diferenciar os alunos dos instrutores e atualizar o modelo de dados. Nenhum código no aplicativo Web precisaria ser alterado, exceto onde você queria mostrar uma data de contratação para os alunos. Outro benefício da adição Instructor e Student das entidades é que seu código é mais facilmente compreensível do que quando se refere a Person objetos que eram, na verdade, alunos ou instrutores.

Agora você viu uma maneira de implementar um padrão de herança no Entity Framework. No tutorial a seguir, você aprenderá a usar procedimentos armazenados para ter mais controle sobre como o Entity Framework acessa o banco de dados.