Compartir a través de


Tutorial: asignar la herencia - tabla por Jerarquía

En este tema se muestra cómo implementar la herencia de tabla por jerarquía modificando el modelo conceptual en un Entity Data Model (EDM). La herencia de tabla por jerarquía emplea una tabla de base de datos para mantener los datos de todos los tipos de entidad en una jerarquía de la herencia. Para obtener más información sobre cómo implementar la herencia con un EDM, vea Herencia (EDM).

En este tutorial, implementará la herencia de tabla por jerarquía modificando el EDM que se usa en la aplicación CourseManager (para obtener más información, consulte la sección Requisitos previos, posteriormente en este tema).

En el EDM de CourseManager, el tipo de entidad Person tiene dos propiedades, HireDate y EnrollmentDate, que pueden pertenecer a los nuevos tipos de entidad (Instructor y Student respectivamente) que heredan de Person. Los pasos siguientes resumen cómo implementar la herencia de tabla por jerarquía en este caso. Los procedimientos de este tutorial proporcionan más detalles.

  1. Cree dos tipos de entidad nuevos, Instructor y Student.

  2. Establezca el tipo base para cada nuevo tipo de entidad en Person.

  3. Mueva la propiedad HireDate de Person a Instructor y mueva la propiedad EnrollmentDate de Person a Student.

  4. Convierta el tipo de entidad Person en un tipo abstracto.

  5. Asigne el tipo de entidad Instructor a la tabla Person con dos condiciones: HireDate Is Not Null y EnrollmentDate Is Null.

  6. Asigne el tipo de entidad Student a la tabla Person con dos condiciones: EnrollmentDate Is Not Null y HireDate Is Null.

Requisitos previos

Para completar este tutorial, debe generar la aplicación CourseManager. Para obtener más información e instrucciones, vea el Tutorial rápido de Entity Framework. Después de generar esta aplicación, modificará su EDM implementando la herencia de tabla por jerarquía. A continuación, extenderá la funcionalidad de la aplicación para mostrar la inscripción para un curso seleccionado.

Nota

Dado que muchos de los temas del tutorial de esta documentación usan la aplicación CourseManager como punto de partida, recomendamos que utilice una copia de la misma en este tutorial, en lugar de modificar el código original de CourseManager.

Este tutorial supone que el lector tiene conocimientos básicos de Visual Studio, .NET Framework y sobre la programación en Visual C# o Visual Basic.

Implementar la herencia de tabla por jerarquía

En este procedimiento, modificará la parte conceptual del EDM de SchoolModel para implementar la herencia de tabla por jerarquía.

Para implementar la herencia de tabla por jerarquía

  1. Abra la solución CourseManager en Visual Studio.

  2. En el Explorador de soluciones, haga doble clic en el archivo School.edmx.

    El archivo School.edmx se abre en ADO.NET Entity Data Model Designer (Entity Designer).

  3. Haga clic con el botón secundario en un área vacía de la superficie de diseño de Entity Designer, seleccione Agregar y, a continuación, haga clic en Entity.

    Aparece el cuadro de diálogo Nueva entidad.

  4. Escriba Instructor como Nombre de entidad y seleccione Person en la lista desplegable para el Tipo base.

  5. Haga clic en Aceptar.

    Se crea y se muestra un nuevo tipo de entidad en la superficie de diseño.

  6. Repita los pasos 3 a 5, pero escriba Student como Nombre de entidad en el segundo paso.

    Ahora tiene dos tipos de entidad nuevos, Instructor y Student, que se muestran en la superficie de diseño. Las flechas señalan desde los nuevos tipos de entidad al tipo de entidad Person; esto indica que Person es el tipo base para los nuevos tipos de entidad.

  7. Haga clic con el botón secundario en la propiedad HireDate (debajo de Propiedades escalares) del tipo de entidad Person. Seleccione Cortar.

  8. Haga clic con el botón secundario en Propiedades escalares del tipo de entidad Instructor y seleccione Pegar.

  9. Haga clic con el botón secundario en la propiedad HireDate y seleccione Propiedades.

  10. En la ventana Propiedades, establezca la propiedad Nullable en false.

  11. Repita los pasos 7 a 10, pero corte la propiedad EnrollmentDate del tipo de entidad Person y péguelo en el tipo de entidad Student.

  12. Seleccione el tipo de entidad Person. En la ventana Propiedades, establezca su propiedad Abstract en true.

    Aparece un cuadro de mensaje que indica que al definir un tipo de entidad como abstracto, se quitarán todas las asignaciones de función existentes para ese tipo. Haga clic en Aceptar.

    Nota

    No tiene que utilizar los tipos abstractos para modelar escenarios en los que se usa la tabla por jerarquía en general. Los tipos abstractos se utilizan en este ejemplo para mostrar su uso en un EDM.

    Nota

    Los pasos restantes de este procedimiento requieren la ventana Detalles de la asignación. Si esta ventana no está visible, haga clic con el botón secundario en la superficie de diseño principal y seleccione Detalles de la asignación.

  13. Seleccione el tipo de entidad Instructor y haga clic en <Agregar una tabla o vista> en la ventana Detalles de la asignación.

    El campo <Agregar una tabla o vista> se convierte en una lista desplegable de tablas o vistas a las que se puede asignar la entidad seleccionada.

  14. En la lista desplegable, seleccione Person.

    La ventana Detalles de la asignación se actualiza con las asignaciones de columnas predeterminadas y una opción para agregar una condición.

  15. Haga clic en <Agregar condición>.

    El campo <Agregar una condición> se convierte en una lista desplegable de columnas para las que se pueden establecer condiciones.

  16. En la lista desplegable, seleccione HireDate.

    Aparece otro campo <Agregar una condición>.

  17. En la columna Operador de la ventana Detalles de la asignación, seleccione Es en la lista desplegable.

  18. En la columna Propiedad/Valor, seleccione No NULL.

  19. Haga clic en <Agregar condición>.

  20. En la lista desplegable, seleccione EnrollmentDate.

  21. En la columna Operador, seleccione Es en la lista desplegable.

  22. En la columna Propiedad/Valor, seleccione NULL.

    Nota

    Si un valor o propiedad se utiliza en una condición que tampoco puede ser una propiedad de entidad, a menos que la condición utilice una comparación Is Null o Is Not Null.

  23. Repita los pasos 13 a 22 para el tipo de entidad Student, pero establezca las condiciones HireDate Is Null y EnrollmentDate Is Not Null.

Ahora se implementa la herencia de tabla por jerarquía.

Construir la interfaz de usuario

Luego, agregará un botón al formulario CourseViewer que carga y muestra el formulario Enrollment. A continuación, agregará dos controles ComboBox y un control ListBox al formulario Enrollment. El primer ComboBox le permite seleccionar un departamento. El segundo ComboBox le permite seleccionar un curso basado en el departamento seleccionado en el primer ComboBox. Una lista de alumnos e instructores para el curso seleccionado se muestra en el control ListBox.

Para construir la interfaz de usuario

  1. Haga clic con el botón secundario en el proyecto CourseManager en el Explorador de soluciones, seleccione Agregar y seleccione Nuevo elemento.

    Aparecerá el cuadro de diálogo Agregar nuevo elemento.

  2. Seleccione Windows Forms, establezca el nombre del formulario en Enrollment.vb o Enrollment.cs (en función del lenguaje que use) y haga clic en Agregar.

    Se agrega un formulario nuevo al proyecto y se abre en el diseñador de formularios. El nombre del formulario se establece en Enrollment y el texto en Enrollment.

  3. Arrastre un control ComboBox del cuadro de herramientas al formulario y establezca su nombre en departmentList en la ventana Propiedades.

  4. Arrastre otro control ComboBox hacia el formulario y establezca su nombre en courseList.

  5. Arrastre un control Listbox del cuadro de herramientas al formulario. Establezca su nombre en studentList en la ventana Propiedades.

  6. En el Explorador de soluciones, haga doble clic en el formulario CourseViewer.cs o CourseViewer.vb.

    La vista de diseño del formulario CourseViewer aparece.

  7. Arrastre un control Button del cuadro de herramientas al formulario CourseViewer.

  8. En la ventana Propiedades, establezca el nombre del botón en viewEnrollment y establezca el texto del botón en View Enrollment.

  9. Haga doble clic en el botón viewEnrollment.

    El archivo de código subyacente para el formulario CourseViewer se abre.

  10. Agregue el código siguiente al controlador de eventos viewEnrollment_click:

    Dim enrollmentForm As New Enrollment()
    enrollmentForm.Visible = True
    
    Enrollment enrollmentForm = new Enrollment();
    enrollmentForm.Visible = true;
    

La interfaz de usuario está completa ahora.

Consultar el EDM

En este procedimiento, consultará el EDM y enlazará los resultados a los controles de formularios Windows Forms. Para obtener más información sobre cómo enlazar objetos a controles, vea Enlazar objetos a controles (Entity Framework).

Para consultar el EDM

  1. Con el formulario Enrollment abierto en el diseñador de formularios, haga doble clic en el formulario Enrollment.

    El archivo de código subyacente para el formulario Enrollment se abre.

  2. Agregue las instrucciones using (C#) o Imports (Visual Basic) siguientes (C#) para hacer referencia al espacio de nombres EDM.

    Imports System.Data.Objects
    Imports System.Data.Objects.DataClasses
    
    using System.Data.Objects;
    using System.Data.Objects.DataClasses;
    
  3. Agregue una propiedad a la clase Enrollment que representa el contexto de datos:

    ' Create an ObjectContext instance based on SchoolEntity.
    Private schoolContext As SchoolEntities
    
    // Create an ObjectContext instance based on SchoolEntity.
    private SchoolEntities schoolContext;
    
  4. En el controlador de eventos Enrollment_Load, agregue el código para inicializar el contexto del objeto y enlazar el control ComboBox a una consulta que devuelve todos los departamentos y la información del curso relacionada.

    ' Initialize the ObjectContext.
    schoolContext = New SchoolEntities()
    
    ' Define a query that returns all Department objects and 
    ' related Course objects, ordered by name.
    Dim departmentQuery As ObjectQuery(Of Department) = _
        schoolContext.Department.Include("Course") _
        .OrderBy("it.Name")
    
    ' Bind the ComboBox control to the query, which is 
    ' executed during data binding.
    Me.departmentList.DataSource = departmentQuery _
    .Execute(MergeOption.OverwriteChanges)
    Me.departmentList.DisplayMember = "Name"
    
        // Initialize the ObjectContext.
        schoolContext = new SchoolEntities();
    
        // Define a query that returns all Department objects
        // and related Course objects, ordered by name.
        ObjectQuery<Department> departmentQuery =
            schoolContext.Department.Include("Course")
                                    .OrderBy("it.Name");
    
        // Bind the ComboBox control to the query, which is
        // executed during data binding.
        this.departmentList.DataSource = departmentQuery
    .Execute(MergeOption.OverwriteChanges);
        this.departmentList.DisplayMember = "Name";
    
  5. Vuelva a la vista de diseño del formulario Enrollment y haga doble clic en el control departmentListComboBox.

    El controlador de eventos departmentList_SelectedIndexChanged se crea en el código subyacente del archivo.

  6. Agregue el código al controlador de eventos para enlazar courseList el control ComboBox a las propiedades Course del Department seleccionado.

    ' Get the object for the selected department
    Dim department As Department = CType(Me.departmentList _
            .SelectedItem, Department)
    
    ' Bind the ComboBox control Course properties of
    ' the selected Department.
    courseList.DataSource = department.Course
    courseList.DisplayMember = "Title"
    
    // Get the object for the selected department.
    Department department =
            (Department)this.departmentList.SelectedItem;
    
    // Bind the ComboBox control Course properties of 
    // the selected Department.
    courseList.DataSource = department.Course;
    courseList.DisplayMember = "Title";
    
  7. Vuelva a la vista de diseño del formulario Enrollment y haga doble clic en el control courseListComboBox.

    El controlador de eventos courseList_SelectedIndexChanged se crea en el código detrás del archivo.

  8. Agregue código al controlador de eventos para mostrar una lista de alumnos en ListBox.

    Me.studentList.Items.Clear()
    
    ' Get the CourseID from the selected Course.
    Dim course As Course = CType(Me.courseList.SelectedItem,  _
         Course)
    Dim courseId As Integer = course.CourseID
    
    ' Get all CourseGrade objects for the supplied CourseID
    Dim studentQuery As Course = schoolContext.Course.Where _
         ("it.CourseID = @courseID", New ObjectParameter _
          ("courseID", courseId)).Include("CourseGrade"). _
          FirstOrDefault()
    
    ' Get all students for each CourseGrade
    For Each cg As CourseGrade In studentQuery.CourseGrade
        cg.PersonReference.Load()
        studentList.Items.Add(cg.Person.LastName + ", " + _
                            cg.Person.FirstName)
    Next
    
    studentList.Items.Add(" ")
    
    ' Get all Instructor types for the supplied CourseID
    Dim instructorQuery As Course = schoolContext.Course. _
         Where("it.CourseID = @courseID", New ObjectParameter _
               ("courseID", courseId)).Include("Person") _
               .FirstOrDefault()
    
    ' Display each instructor for the specified Course
    For Each Instructor As Instructor In instructorQuery.Person
        Me.studentList.Items.Add("Instructor: " + Instructor. _
                        LastName + ", " + Instructor.FirstName)
    Next
    
    studentList.Items.Clear();
    
    // Get the CourseID from the selected Course.
    Course course = (Course)courseList.SelectedItem;
    int courseId = course.CourseID;
    
    // Get all CourseGrade types for the supplied CourseID
    Course studentQuery = schoolContext.Course.Where(
        "it.CourseID = @courseID", new ObjectParameter
            ("courseID", courseId)).Include("CourseGrade").
            FirstOrDefault();
    
    // Get all students for each CourseGrade
    foreach (CourseGrade cg in studentQuery.CourseGrade)
    {
        cg.PersonReference.Load();
        studentList.Items.Add(cg.Person.LastName + ", " +
            cg.Person.FirstName);
    }
    
    studentList.Items.Add(" ");
    
    // Get all Instructor types for the supplied CourseID
    Course instructorQuery = schoolContext.Course.Where(
        "it.CourseID = @courseID", new ObjectParameter
            ("courseID", courseId)).Include("Person").
            FirstOrDefault();
    
    // Display each instructor for the specified course.
    foreach (Instructor instructor in instructorQuery.Person.
        OfType<Instructor>())
    {
        studentList.Items.Add("Instructor: " + instructor.
            LastName + ", " + instructor.FirstName);
    }
    

La aplicación se ha completado ahora. Presione Ctrl+F5 para ejecutar la aplicación. Haga clic en el botón View Enrollment para cargar el formulario Enrollment. La inscripción del curso e instructores para el curso seleccionado se muestran en ListBox.

Códigos

Esta sección muestra la versión final del archivo de código subyacente para el formulario Enrollment.

Imports System.Data.Objects
Imports System.Data.Objects.DataClasses

Public Class Enrollment

    ' Create an ObjectContext instance based on SchoolEntity.
    Private schoolContext As SchoolEntities

    Private Sub Enrollment_Load(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles MyBase.Load
        ' Initialize the ObjectContext.
        schoolContext = New SchoolEntities()

        ' Define a query that returns all Department objects and 
        ' related Course objects, ordered by name.
        Dim departmentQuery As ObjectQuery(Of Department) = _
            schoolContext.Department.Include("Course") _
            .OrderBy("it.Name")

        ' Bind the ComboBox control to the query, which is 
        ' executed during data binding.
        Me.departmentList.DataSource = departmentQuery _
        .Execute(MergeOption.OverwriteChanges)
        Me.departmentList.DisplayMember = "Name"
    End Sub

    Private Sub departmentList_SelectedIndexChanged(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) Handles _
            departmentList.SelectedIndexChanged
        ' Get the object for the selected department
        Dim department As Department = CType(Me.departmentList _
                .SelectedItem, Department)

        ' Bind the ComboBox control Course properties of
        ' the selected Department.
        courseList.DataSource = department.Course
        courseList.DisplayMember = "Title"
    End Sub

    Private Sub courseList_SelectedIndexChanged(ByVal sender As  _
            System.Object, ByVal e As System.EventArgs) Handles _
            courseList.SelectedIndexChanged
        Me.studentList.Items.Clear()

        ' Get the CourseID from the selected Course.
        Dim course As Course = CType(Me.courseList.SelectedItem,  _
             Course)
        Dim courseId As Integer = course.CourseID

        ' Get all CourseGrade objects for the supplied CourseID
        Dim studentQuery As Course = schoolContext.Course.Where _
             ("it.CourseID = @courseID", New ObjectParameter _
              ("courseID", courseId)).Include("CourseGrade"). _
              FirstOrDefault()

        ' Get all students for each CourseGrade
        For Each cg As CourseGrade In studentQuery.CourseGrade
            cg.PersonReference.Load()
            studentList.Items.Add(cg.Person.LastName + ", " + _
                                cg.Person.FirstName)
        Next

        studentList.Items.Add(" ")

        ' Get all Instructor types for the supplied CourseID
        Dim instructorQuery As Course = schoolContext.Course. _
             Where("it.CourseID = @courseID", New ObjectParameter _
                   ("courseID", courseId)).Include("Person") _
                   .FirstOrDefault()

        ' Display each instructor for the specified Course
        For Each Instructor As Instructor In instructorQuery.Person
            Me.studentList.Items.Add("Instructor: " + Instructor. _
                            LastName + ", " + Instructor.FirstName)
        Next
    End Sub
End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Objects;
using System.Data.Objects.DataClasses;

namespace CourseManager
{
    public partial class Enrollment : Form
    {
        // Create an ObjectContext instance based on SchoolEntity.
        private SchoolEntities schoolContext;

        public Enrollment()
        {
            InitializeComponent();
        }

        private void Enrollment_Load(object sender, EventArgs e)
        {
            // Initialize the ObjectContext.
            schoolContext = new SchoolEntities();

            // Define a query that returns all Department objects
            // and related Course objects, ordered by name.
            ObjectQuery<Department> departmentQuery =
                schoolContext.Department.Include("Course")
                                        .OrderBy("it.Name");

            // Bind the ComboBox control to the query, which is
            // executed during data binding.
            this.departmentList.DataSource = departmentQuery
        .Execute(MergeOption.OverwriteChanges);
            this.departmentList.DisplayMember = "Name";
        }

        private void departmentList_SelectedIndexChanged(object sender, 
            EventArgs e)
        {
            // Get the object for the selected department.
            Department department =
                    (Department)this.departmentList.SelectedItem;

            // Bind the ComboBox control Course properties of 
            // the selected Department.
            courseList.DataSource = department.Course;
            courseList.DisplayMember = "Title";
        }

        private void courseList_SelectedIndexChanged(object sender, 
            EventArgs e)
        {
            studentList.Items.Clear();

            // Get the CourseID from the selected Course.
            Course course = (Course)courseList.SelectedItem;
            int courseId = course.CourseID;

            // Get all CourseGrade types for the supplied CourseID
            Course studentQuery = schoolContext.Course.Where(
                "it.CourseID = @courseID", new ObjectParameter
                    ("courseID", courseId)).Include("CourseGrade").
                    FirstOrDefault();

            // Get all students for each CourseGrade
            foreach (CourseGrade cg in studentQuery.CourseGrade)
            {
                cg.PersonReference.Load();
                studentList.Items.Add(cg.Person.LastName + ", " +
                    cg.Person.FirstName);
            }

            studentList.Items.Add(" ");

            // Get all Instructor types for the supplied CourseID
            Course instructorQuery = schoolContext.Course.Where(
                "it.CourseID = @courseID", new ObjectParameter
                    ("courseID", courseId)).Include("Person").
                    FirstOrDefault();

            // Display each instructor for the specified course.
            foreach (Instructor instructor in instructorQuery.Person.
                OfType<Instructor>())
            {
                studentList.Items.Add("Instructor: " + instructor.
                    LastName + ", " + instructor.FirstName);
            }
        } 
    }
}

Pasos siguientes

Ha implementado correctamente la herencia de tabla por jerarquía en un EDM. Para obtener más información sobre cómo definir un EDM con herencia de tabla por jerarquía, vea Cómo definir un modelo con herencia de tabla por jerarquía (Entity Framework). Para obtener más información sobre cómo generar aplicaciones con Entity Framework, vea Guía de programación (Entity Framework).

Vea también

Otros recursos

Escenarios de ADO.NET Entity Data Model Designer
Tareas de herramientas de Entity Data Model