Novedades de Entity Framework 4.0

por Tom Dykstra

Esta serie de tutoriales se basa en la aplicación web Contoso University creada por la serie de tutoriales Introducción a Entity Framework. Si no completó los tutoriales anteriores, como punto de partida de este tutorial, puede descargar la aplicación que habría creado. También puede descargar la aplicación creada mediante la serie de tutoriales completados. Si tiene preguntas sobre los tutoriales, puede publicarlas en el foro de ASP.NET Entity Framework.

En el tutorial anterior ha visto algunos métodos para maximizar el rendimiento de una aplicación web que usa Entity Framework. En este tutorial se revisan algunas de las características nuevas más importantes de la versión 4 de Entity Framework y se vinculan a recursos que proporcionan una introducción más completa a todas las nuevas características. Las características resaltadas en este tutorial incluyen lo siguiente:

  • Asociaciones de claves externas.
  • Ejecución de comandos SQL definidos por el usuario.
  • Desarrollo centrado en el modelo.
  • Compatibilidad con POCO.

Además, el tutorial presentará brevemente el desarrollo orientado al código, una característica que estará disponible en la próxima versión de Entity Framework.

Para comenzar el tutorial, inicie Visual Studio y abra la aplicación web de Contoso University con la que estaba trabajando en el tutorial anterior.

Asociaciones de claves externas

La versión 3.5 de Entity Framework incluía propiedades de navegación, pero no incluía propiedades de clave externa en el modelo de datos. Por ejemplo, las columnas CourseID y StudentID de la tabla StudentGrade se omitirían de la entidad StudentGrade.

Image01

La razón de este enfoque era que, estrictamente hablando, las claves externas son un detalle de implementación física y no pertenecen a un modelo de datos conceptual. Sin embargo, como cuestión práctica, a menudo es más fácil trabajar con entidades en el código cuando se tiene acceso directo a las claves externas.

Para ver un ejemplo de cómo las claves externas del modelo de datos pueden simplificar el código, considere cómo habría tenido que programar la página DepartmentsAdd.aspx sin ellas. En la entidad Department, la propiedad Administrator es una clave externa que corresponde a PersonID en la entidad Person. Para establecer la asociación entre un nuevo departamento y su administrador, todo lo que tenía que hacer era establecer el valor de la propiedad Administrator en el controlador de eventos ItemInserting del control de enlace de datos:

protected void DepartmentsDetailsView_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
    e.Values["Administrator"] = administratorsDropDownList.SelectedValue;
}

Sin claves externas en el modelo de datos, controlaría el evento Inserting del control de origen de datos en lugar del evento ItemInserting del control de entrada de datos, para obtener una referencia a la propia entidad antes de agregarla al conjunto de entidades. Cuando tenga esa referencia, establecerá la asociación mediante código, como en los ejemplos siguientes:

departmentEntityToBeInserted.PersonReference.EntityKey = new System.Data.EntityKey("SchoolEntities.Departments", "PersonID", Convert.ToInt32(administratorsDropDownList.SelectedValue));
departmentEntityToBeInserted.Person = context.People.Single(p => p.PersonID == Convert.ToInt32(administratorsDropDownList.SelectedValue));

Como puede ver en la entrada de blog sobre las asociaciones de clave externa de Entity Framework, hay otros casos en los que la diferencia en la complejidad del código es mucho mayor. Para satisfacer las necesidades de aquellos que prefieren vivir con los detalles de implementación del modelo de datos conceptual para simplificar el código, Entity Framework ahora ofrece la opción de incluir claves externas en el modelo de datos.

En la terminología de Entity Framework, si incluye claves externas en el modelo de datos, está usando asociaciones de claves externas y si excluye las claves externas, está usando asociaciones independientes.

Ejecución de comandos SQL definidos por el usuario

En versiones anteriores de Entity Framework, no había ninguna manera fácil de crear sus propios comandos SQL sobre la marcha y ejecutarlos. O Entity Framework generaba dinámicamente comandos SQL o usted tenía que crear un procedimiento almacenado e importarlo como una función. La versión 4 agrega los métodos ExecuteStoreQuery y ExecuteStoreCommand a la clase ObjectContext, lo que facilita el paso de cualquier consulta directamente a la base de datos.

Supongamos que los administradores de Contoso University quieren poder realizar cambios masivos en la base de datos sin tener que pasar por el proceso de creación de un procedimiento almacenado y su importación en el modelo de datos. Su primera solicitud es para una página que les permite cambiar el número de créditos de todos los cursos de la base de datos. En la página web, quieren poder insertar un número que se usará para multiplicar el valor de la columna Credits de cada fila Course.

Cree una página que use la página maestra Site.Master y llámela UpdateCredits.aspx. Agregue el marcado siguiente al control Content denominado Content2:

<h2>Update Credits</h2>
    Enter the number to multiply the current number of credits by: 
    <asp:TextBox ID="CreditsMultiplierTextBox" runat="server"></asp:TextBox>
    <br /><br />
    <asp:Button ID="ExecuteButton" runat="server" Text="Execute" OnClick="ExecuteButton_Click" /><br /><br />
    Rows affected:
    <asp:Label ID="RowsAffectedLabel" runat="server" Text="0" ViewStateMode="Disabled"></asp:Label><br /><br />

Este marcado crea un control TextBox en el que el usuario puede insertar el valor multiplicador, un control Button para hacer clic para ejecutar el comando y un control Label para indicar el número de filas afectadas.

Abra UpdateCredits.aspx.cs y agregue la siguiente instrucción using y un controlador para el evento Click del botón:

using ContosoUniversity.DAL;
protected void ExecuteButton_Click(object sender, EventArgs e)
{
    using (SchoolEntities context = new SchoolEntities())
    {
        RowsAffectedLabel.Text = context.ExecuteStoreCommand("UPDATE Course SET Credits = Credits * {0}", CreditsMultiplierTextBox.Text).ToString();
    }
}

Este código ejecuta el comando SQL Update usando el valor del cuadro de texto y usa la etiqueta para mostrar el número de filas afectadas. Antes de ejecutar la página, ejecute la página Courses.aspx para obtener una imagen del "antes" de algunos datos.

Image02

Ejecute UpdateCredits.aspx, escriba "10" como multiplicador y, a continuación, haga clic en Ejecutar.

Image03

Vuelva a ejecutar la página Courses.aspx para ver los datos modificados.

Image04

(Si quiere devolver el número de créditos a sus valores originales, en UpdateCredits.aspx.cs cambie Credits * {0} a Credits / {0} y vuelva a ejecutar la página, escribiendo 10 como divisor).

Para más información sobre cómo ejecutar consultas que defina en el código, consulte Ejecución de comandos directamente con respecto al origen de datos.

Desarrollo centrado en el modelo

En estos tutoriales creó primero la base de datos y, luego, generó el modelo de datos basado en la estructura de la base de datos. En Entity Framework 4, puede empezar con el modelo de datos y generar la base de datos en función de este. Si va a crear una aplicación para la que la base de datos aún no existe, el enfoque centrado en el modelo le permite crear entidades y relaciones que tengan sentido conceptualmente para la aplicación sin preocuparse por los detalles de la implementación física. (Sin embargo, esto solo es cierto en las fases iniciales de desarrollo. Finalmente, se creará la base de datos, que tendrá datos de producción, y ya no será práctico volver a crearla a partir del modelo; en ese momento volverá al enfoque centrado en la base de datos).

En esta sección del tutorial, creará un modelo de datos sencillo y generará la base de datos a partir de él.

En el Explorador de soluciones, haga clic con el botón derecho en la carpeta DAL y seleccione Agregar nuevo elemento. En el cuadro de diálogo Agregar nuevo elemento, en Plantillas instaladas, seleccione Datos y, luego, seleccione la plantilla Entity Data Model de ADO.NET. Llame al nuevo archivo AlumniAssociationModel.edmx y haga clic en Agregar.

Image06

Se inicia el Asistente de Entity Data Model. En el paso Elegir contenido del modelo, seleccione Modelo vacío y, luego, haga clic en Finalizar.

Image07

Se abre el Diseñador de Entity Data Model con una superficie de diseño en blanco. Arrastre un elemento Entity desde el cuadro de herramientas hasta la superficie de diseño.

Image08

Cambie el nombre de entidad de Entity1 a Alumnus, cambie el nombre de la propiedad Id a AlumnusId y agregue una nueva propiedad escalar denominada Name. Para agregar nuevas propiedades, puede presionar Entrar después de cambiar el nombre de la columna Id o hacer clic con el botón derecho en la entidad y seleccionar Agregar propiedad escalar. El tipo predeterminado de las nuevas propiedades es String, que es adecuado para esta demostración sencilla, pero, por supuesto, puede cambiar cosas como el tipo de datos en la ventana Propiedades.

Cree otra entidad de la misma manera y llámela Donation. Cambie la propiedad Id a DonationId y agregue una propiedad escalar denominada DateAndAmount.

Image09

Para agregar una asociación entre estas dos entidades, haga clic con el botón derecho en la entidad Alumnus, seleccione Agregar y, luego, elija Asociación.

Image10

Los valores predeterminados del cuadro de diálogo Agregar asociación son los que desea (de uno a varios, incluir propiedades de navegación, incluir claves externas), por lo que simplemente haga clic en Aceptar.

Image11

El diseñador agrega una línea de asociación y una propiedad de clave externa.

Image12

Ahora está listo para crear la base de datos. Haga clic con el botón derecho en la superficie de diseño y seleccione Generar base de datos desde modelo.

Image13

Esta acción inicia el Asistente para generar base de datos. (Si ve advertencias que indican que las entidades no están asignadas, puede omitirlas por el momento).

En la página Elegir la conexión de datos, haga clic en Nueva conexión.

Image14

En el cuadro de diálogo Propiedades de conexión, seleccione la instancia local de SQL Server Express y asigne a la base de datos el nombre AlumniAssociation.

Image15

Cuando se le pregunte si desea crear la base de datos, haga clic en . Cuando se vuelva a mostrar el paso Elegir la conexión de datos, haga clic en Siguiente.

En el paso Resumen y configuración, haga clic en Finalizar.

Image18

Se crea un archivo .sql con los comandos del lenguaje de definición de datos (DDL), pero los comandos aún no se han ejecutado.

Image20

Use una herramienta como SQL Server Management Studio para ejecutar el script y crear las tablas, como podría haber hecho cuando creó la base de datos School en el primer tutorial de la serie de tutoriales de introducción. (A menos que haya descargado la base de datos).

Ahora puede usar el modelo de datos AlumniAssociation en las páginas web de la misma manera que ha estado usando el modelo School. Para probar esto, agregue algunos datos a las tablas y cree una página web que muestre los datos.

Con el Explorador de servidores, agregue las siguientes filas a las tablas Alumnus y Donation.

Image21

Cree una nueva página web denominada Alumni.aspx que use la página maestra Site.Master. Agregue el marcado siguiente al control Content denominado Content2:

<h2>Alumni</h2>
    <asp:EntityDataSource ID="AlumniEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.AlumniAssociationModelContainer" EnableFlattening="False" 
        EntitySetName="Alumni">
    </asp:EntityDataSource>
    <asp:GridView ID="AlumniGridView" runat="server" 
        DataSourceID="AlumniEntityDataSource" AutoGenerateColumns="False"
        OnRowDataBound="AlumniGridView_RowDataBound"
        DataKeyNames="AlumnusId">
        <Columns>
            <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
            <asp:TemplateField HeaderText="Donations">
                <ItemTemplate>
                    <asp:GridView ID="DonationsGridView" runat="server" AutoGenerateColumns="False">
                        <Columns>
                            <asp:BoundField DataField="DateAndAmount" HeaderText="Date and Amount" />
                        </Columns>
                    </asp:GridView>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

Este marcado crea controles GridView anidados, el exterior para mostrar nombres de alumnos y el interior para mostrar fechas y cantidades de donaciones.

Abra Alumni.aspx.cs. Agregue una instrucción using para la capa de acceso a datos y un controlador para el evento RowDataBound del control externo GridView:

using ContosoUniversity.DAL; 

// ...

protected void AlumniGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        var alumnus = e.Row.DataItem as Alumnus;
        var donationsGridView = (GridView)e.Row.FindControl("DonationsGridView");
        donationsGridView.DataSource = alumnus.Donations.ToList();
        donationsGridView.DataBind();
    }
}

Este código enlaza los datos del control interno GridView mediante la propiedad de navegación Donations de la entidad Alumnus de la fila actual.

Ejecute la página.

Image22

(Nota: Esta página se incluye en el proyecto descargable, pero, para que funcione, debe crear la base de datos en la instancia local de SQL Server Express; la base de datos no se incluye como un archivo .mdf en la carpeta App_Data).

Para más información sobre el uso de la característica de desarrollo centrado en el modelo de Entity Framework, consulte Desarrollo centrado en el modelo de Entity Framework 4.

Compatibilidad con POCO

Cuando se usa la metodología de diseño centrada en el dominio, se diseñan clases de datos que representan datos y comportamientos relevantes para el dominio empresarial. Estas clases deben ser independientes de cualquier tecnología específica utilizada para almacenar (conservar) los datos; en otras palabras, deben ser ignorantes de persistencia. La ignorancia de persistencia también puede facilitar la prueba unitaria de una clase, ya que el proyecto de prueba unitaria puede usar la tecnología de persistencia que sea más conveniente para las pruebas. Las versiones anteriores de Entity Framework ofrecían compatibilidad limitada con la ignorancia de persistencia porque las clases de entidad tenían que heredar de la clase EntityObject y, por tanto, incluían una gran cantidad de funcionalidad específica de Entity Framework.

Entity Framework 4 ofrece la posibilidad de usar clases de entidad que no heredan de la clase EntityObject y, por tanto, son ignorantes de persistencia. En el contexto de Entity Framework, las clases como esta suelen denominarse objetos CLR antiguos sin formato (POCO). Puede escribir clases POCO manualmente o puede generarlas automáticamente en función de un modelo de datos existente mediante plantillas Text Template Transformation Toolkit (T4) proporcionadas por Entity Framework.

Para más información sobre el uso de objetos POCO en Entity Framework, consulte los siguientes recursos:

Desarrollo centrado en el código

Para la compatibilidad con POCO en Entity Framework 4, aún es necesario que cree un modelo de datos y vincule las clases de entidad al modelo de datos. La próxima versión de Entity Framework incluirá una característica denominada desarrollo centrado en el código. Esta característica permite usar Entity Framework con sus propias clases POCO sin necesidad de usar el diseñador de modelos de datos o un archivo XML del modelo de datos. (Por lo tanto, esta opción también se ha llamado solo código; código primero y solo código hacen referencia ambos a la misma característica de Entity Framework.)

Para más información sobre el uso del enfoque de desarrollo centrado en el código, consulte los siguientes recursos:

Además, está previsto que en la primavera de 2011 se publique un nuevo tutorial sobre el desarrollo centrado en el código de MVC que compila una aplicación similar a la aplicación Contoso University, en https://asp.net/entity-framework/tutorials.

Más información

Así finaliza el resumen de las novedades de Entity Framework y continúa con la serie de tutoriales de Entity Framework. Para más información sobre las nuevas características de Entity Framework 4 que no se tratan aquí, consulte los siguientes recursos: