Introducción a Entity Framework 4.0 Database First y ASP.NET 4 Web Forms: parte 6
Por Tom Dykstra
En la aplicación web de ejemplo Contoso University se muestra cómo crear aplicaciones ASP.NET Web Forms con Entity Framework 4.0 y Visual Studio 2010. Para obtener información sobre la serie de tutoriales, consulte el primer tutorial de la serie
Implementar la herencia de tabla por jerarquía
En el tutorial anterior ha trabajado con datos relacionados agregando y eliminando relaciones y agregando una nueva entidad que tenía una relación con una entidad existente. En este tutorial se muestra cómo implementar la herencia en el modelo de datos.
En la programación orientada a objetos, puede usar la herencia para facilitar el trabajo con clases relacionadas. Por ejemplo, podría crear Instructor
y Student
clases que derivan de una Person
clase base. Puede crear los mismos tipos de estructuras de herencia entre las entidades de Entity Framework.
En esta parte del tutorial, no creará ninguna página web nueva. En su lugar, agregará entidades derivadas al modelo de datos y modificará las páginas existentes para usar las nuevas entidades.
Herencia de tabla por jerarquía frente a herencia de tabla por tipo
Una base de datos puede almacenar información sobre objetos relacionados en una tabla o en varias tablas. Por ejemplo, en la School
base de datos, la Person
tabla incluye información sobre alumnos e instructores en una sola tabla. Algunas de las columnas solo se aplican a los instructores (HireDate
), algunas solo a los alumnos (EnrollmentDate
) y algunas a ambas (LastName
, FirstName
).
Puede configurar Entity Framework para crear Instructor
y Student
entidades que hereden de la Person
entidad. Este patrón de generación de una estructura de herencia de la entidad a partir de una tabla de base de datos única, se denomina herencia de tabla por jerarquía (TPH) .
En el caso de los cursos, la School
base de datos usa un patrón diferente. Los cursos en línea y los cursos in situ se almacenan en tablas independientes, cada una de las cuales tiene una clave externa que apunta a la Course
tabla. La información común a ambos tipos de curso solo se almacena en la Course
tabla.
Puede configurar el modelo de datos de Entity Framework para que OnlineCourse
y OnsiteCourse
las entidades hereden de la Course
entidad. Este patrón de generación de una estructura de herencia de entidades a partir de tablas independientes para cada tipo, con cada tabla independiente que hace referencia a una tabla que almacena datos comunes a todos los tipos, se denomina herencia de tabla por tipo (TPT).
Los patrones de herencia TPH suelen ofrecer un mejor rendimiento en Entity Framework que los patrones de herencia TPT, porque los patrones TPT pueden dar lugar a consultas join complejas. En este tutorial se muestra cómo implementar la herencia de TPH. Para ello, realice los pasos siguientes:
- Cree
Instructor
tipos de entidad yStudent
que deriven dePerson
. - Mueva las propiedades que pertenecen a las entidades derivadas de la
Person
entidad a las entidades derivadas. - Establezca restricciones en las propiedades de los tipos derivados.
- Convierta la
Person
entidad en una entidad abstracta. - Asigne cada entidad derivada a la
Person
tabla con una condición que especifique cómo determinar si unaPerson
fila representa ese tipo derivado.
Adición de entidades instructora y estudiante
Abra el archivo SchoolModel.edmx, haga clic con el botón derecho en un área no ocupada en el diseñador, seleccione Agregary, a continuación, seleccione Entidad.
En el cuadro de diálogo Agregar entidad, asigne el nombre a la entidadInstructor
y establezca su opción Tipo base enPerson
.
Haga clic en OK. El diseñador crea una Instructor
entidad que deriva de la Person
entidad. La nueva entidad aún no tiene ninguna propiedad.
Repita el procedimiento para crear una Student
entidad que también derive de Person
.
Solo los instructores tienen fechas de contratación, por lo que debe mover esa propiedad de la Person
entidad a la Instructor
entidad. En la entidad, haga clic con el Person
botón derecho en la HireDate
propiedad y haga clic en Cortar. A continuación, haga clic con el botón derecho en Propiedades en laInstructor
entidad y haga clic en Pegar .
La fecha de contratación de una Instructor
entidad no puede ser null. Haga clic con el botón derecho en la propiedad HireDate
, haga clic en Propiedades y, a continuación, en la ventana Propiedades cambie Nullable
a False
.
Repita el procedimiento para mover la EnrollmentDate
propiedad de la Person
entidad a la Student
entidad. Asegúrese de establecer también Nullable
en False
para la propiedad EnrollmentDate
.
Ahora que una Person
entidad solo tiene las propiedades comunes a Instructor
las entidades y Student
(aparte de las propiedades de navegación, que no se mueven), la entidad solo se puede usar como una entidad base en la estructura de herencia. Por lo tanto, debe asegurarse de que nunca se trata como una entidad independiente. Haga clic con el botón derecho en la Person
entidad, seleccione Propiedades y, a continuación, en la ventana Propiedades, cambie el valor de la propiedad Abstract a True.
Asignar entidades de instructor y alumno a la tabla person
Ahora debe indicar a Entity Framework cómo diferenciar entre Instructor
las entidades y Student
en la base de datos.
Haga clic con el botón secundario en el tipo de entidad Instructor
y seleccione Asignación de tabla. En la ventana Detalles de asignación, haga clic en Agregar una tabla o vista y seleccione Persona.
Haga clic en Agregar una condicióny, a continuación, seleccione HireDate.
Cambie el operador a Is y Value /Property a Not Null.
Repita el procedimiento para la Students
entidad y especifique que esta entidad se asigna a la Person
tabla cuando la EnrollmentDate
columna no es null. A continuación, guarde y cierre el modelo de datos.
Compile el proyecto para crear las nuevas entidades como clases y ponerlas a disposición del diseñador.
Uso de las entidades Instructor y Student
Cuando creó las páginas web que funcionan con datos de alumno e instructor, los datos se enlazaron al Person
conjunto de entidades y filtre por la HireDate
propiedad o EnrollmentDate
para restringir los datos devueltos a los alumnos o instructores. Sin embargo, ahora, al enlazar cada control de origen de datos al Person
conjunto de entidades, puede especificar que solo se deben seleccionar los tipos de entidad Student
o Instructor
. Dado que Entity Framework sabe cómo diferenciar alumnos e instructores en el Person
conjunto de entidades, puede quitar la Where
configuración de propiedad que escribió manualmente para hacerlo.
En el Diseñador de Visual Studio, puede especificar el tipo de entidad que un EntityDataSource
control debe seleccionar en el cuadro desplegable EntityTypeFilter del Configure Data Source
asistente, como se muestra en el ejemplo siguiente.
Y en la ventana Propiedades puede quitar Where
los valores de cláusula que ya no son necesarios, como se muestra en el ejemplo siguiente.
Sin embargo, dado que ha cambiado el marcado para EntityDataSource
que los controles usen el ContextTypeName
atributo, no puede ejecutar el Asistente para configurar orígenes de datos en los controles EntityDataSource
que ya ha creado. Por lo tanto, realizará los cambios necesarios cambiando el marcado en su lugar.
Abra la página Students.aspx. En el StudentsEntityDataSource
control, quite el Where
atributo y agregue un EntityTypeFilter="Student"
atributo. El marcado será ahora similar al ejemplo siguiente:
<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>
Establecer el EntityTypeFilter
atributo garantiza que el EntityDataSource
control seleccione solo el tipo de entidad especificado. Si desea recuperar los tipos de Student
entidad y Instructor
, no establecería este atributo. (Tiene la opción de recuperar varios tipos de entidad con un EntityDataSource
solo control si usa el control para el acceso a datos de solo lectura. Si usa un EntityDataSource
control para insertar, actualizar o eliminar entidades, y si el conjunto de entidades al que está enlazado puede contener varios tipos, solo puede trabajar con un tipo de entidad y debe establecer este atributo).
Repita el procedimiento para el SearchEntityDataSource
control, excepto quite solo la parte del Where
atributo que selecciona Student
entidades en lugar de quitar la propiedad por completo. La etiqueta de apertura del control se parecerá al ejemplo siguiente:
<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 + '%'" >
Ejecute la página para comprobar que sigue funcionando como hizo antes.
Actualice las páginas siguientes que creó en tutoriales anteriores para que usen las entidades y nuevas Student
Instructor
en lugar de Person
las entidades y, a continuación, ejecútelos para comprobar que funcionan como lo hicieron antes:
En StudentsAdd.aspx, agregue
EntityTypeFilter="Student"
al controlStudentsEntityDataSource
. El marcado será ahora similar al ejemplo siguiente:<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" EntitySetName="People" EntityTypeFilter="Student" EnableInsert="True" </asp:EntityDataSource>
En About.aspx, agregue
EntityTypeFilter="Student"
alStudentStatisticsEntityDataSource
control y quiteWhere="it.EnrollmentDate is not null"
. El marcado será ahora similar al ejemplo siguiente:<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>
En Instructors.aspx y InstructorsCourses.aspx, agregue al
EntityTypeFilter="Instructor"
controlInstructorsEntityDataSource
y quiteWhere="it.HireDate is not null"
. El marcado de Instructors.aspx ahora es similar al ejemplo siguiente:<asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false" EntitySetName="People" EntityTypeFilter="Instructor" Include="OfficeAssignment" EnableUpdate="True"> </asp:EntityDataSource>
El marcado de InstructorsCourses.aspx ahora será similar al ejemplo siguiente:
<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>
Como resultado de estos cambios, ha mejorado la capacidad de mantenimiento de la aplicación Contoso University de varias maneras. Ha movido la lógica de selección y validación fuera de la capa de interfaz de usuario (.aspx marcado) y lo ha convertido en una parte integral de la capa de acceso a datos. Esto ayuda a aislar el código de la aplicación de los cambios que puede realizar en el futuro en el esquema de la base de datos o el modelo de datos. Por ejemplo, podría decidir que los alumnos podrían contratarse como ayudas para profesores y, por lo tanto, obtenería una fecha de contratación. A continuación, podría agregar una nueva propiedad para diferenciar a los alumnos de instructores y actualizar el modelo de datos. Ningún código de la aplicación web tendría que cambiar, excepto donde quería mostrar una fecha de contratación para estudiantes. Otra ventaja de agregar Instructor
y Student
entidades es que el código es más fácil de entender que cuando se hace referencia a Person
objetos que eran realmente alumnos o instructores.
Ahora ha visto una manera de implementar un patrón de herencia en Entity Framework. En el siguiente tutorial, aprenderá a usar procedimientos almacenados para tener más control sobre cómo Entity Framework accede a la base de datos.