Entity Framework (I): Creación de un Entity Model


Entity Framework es la evolución natural de ADO.NET hacia el tratamiento de los datos almacenados en una base de datos relacional a través del paradigma objetual. Por lo tanto, se trata, al igual que LINQ to SQL, de un mapper objeto-relacional que es capaz de abstraer las tablas y columnas de una base de datos y tratarlas como objetos u entidades y relaciones.

Una entidad, por tanto, no es más que un objeto persistente, que cumple las condiciones de unicidad e identidad.

Añadiendo un Entity Data Model

Lo primero que deberemos hacer una vez que hayamos creado nuestro proyecto (por ejemplo, de consola) será añadir un nuevo Entity Data Model. Para ello haremos click derecho sobre nuestro proyecto y seleccionaremos la opción Add > New Item…

Una vez en el diálogo de selección, navegamos hasta la sección Data y seleccionamos el elemento ADO.NET Entity Data Model, al que le daremos un nombre identificativo.

Una vez añadido, se nos preguntará el modo de generación del modelo. Queremos mapear automáticamente nuestra base de datos, por lo que seleccionaremos la primera opción (Generate from database).

A continuación rellenaremos los datos de conexión para acceder a la base de datos.

El siguiente paso será seleccionar los elementos que queremos importar. Elegimos aquellos que nos interese modelar, le asignamos un nombre al namespace y pulsamos el botón Finish.
La opción Pluralize or singularize generated object names teóricamente se encarga de asignar un nombre en plural a las colecciones y hacerlo singular en las referencias. Sin embargo, según mi experiencia previa con la pluralización automática, es más aconsejable realizarlo a mano (salvo que no tengamos tiempo y se trata de una base de datos enorme).

El resultado será el siguiente: un modelo con sus relativas relaciones que mantiene gran similitud con el modelo relacional.

Como podemos ver, los objetos se componen de propiedades (Properties) y de propiedades de navegación (Navigation Properties), que simbolizarán elementos o conjuntos de elementos con los que la entidad esté relacionada (por ejemplo, Cliente posee una propiedad de navegación Pedido que simbolizará el conjunto de entidades Pedido con los que un cliente está relacionado).

En este punto, hay que destacar un par de detalles:

  • Es obligatorio que cada entidad posea al menos una clave de entidad. En caso contrario, Entity Framework no podrá utilizarse con ese elemento. La clave de entidad se importa automáticamente de la base de datos (clave primaria).
  • Las propiedades de navegación son de dos tipos, dependiendo de la relación:
    • Si la relación es 1:*, la parte “1” tendrá un listado compuesto por uno o más elementos del lado “n”
      • Por ejemplo, Cliente posee una propiedad Pedido, que es un listado de sus pedidos asociados.
    • Si la relación es 1:*, la parte “n” tendrá una referencia a un único objeto del elemento del lado “1”
      • Por ejemplo, Pedido posee una propiedad Cliente, que se corresponde con el Cliente al cual están asociados los pedidos.
  • Es buena práctica cambiar el nombre de los listados a plural y mantener las referencias a objetos individuales en singular. De este modo, la nomenclatura ayudará a distinguir cuándo se trata de un listado o de un único elemento.

Si abrimos el documento XML perteneciente al fichero .edmx, vemos que por un lado generará información sobre la parte relacional y por otro, sobre la parte objetual, realizando el mapeo objeto-relacional.


<!-- SSDL content -->
       <EntityType Name="Cliente">
          <Key>
            <PropertyRef Name="IdCliente" />
          </Key>
          <Property Name="IdCliente" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="Nombre" Type="nvarchar" Nullable="false" MaxLength="50" />
          <Property Name="FechaNacimiento" Type="date" Nullable="false" />
        </EntityType>

<!-- CSDL content -->
        <EntityType Name="Cliente">
          <Key>
            <PropertyRef Name="IdCliente" />
          </Key>
          <Property Name="IdCliente" Type="Int32" Nullable="false" p1:StoreGeneratedPattern="Identity" />
          <Property Name="Nombre" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
          <Property Name="FechaNacimiento" Type="DateTime" Nullable="false" Precision="0" />
          <NavigationProperty Name="Pedido" Relationship="GestionPedidos.FK_Pedido_Cliente" FromRole="Cliente" ToRole="Pedido" />
        </EntityType>

Si desplegamos el fichero .edmx, vemos que, además, contiene un conjunto de ficheros, divididos en Context y Model. La parte del contexto se encargará de realizar las operaciones comunes sobre las entidades, que se alojarán en la parte del modelo.

El modelo de una entidad será, por lo tanto, un POCO cuyas propiedades se corresponderán con las mapeadas a partir del modelo relacional. Por ejemplo, el siguiente POCO simboliza una entidad de tipo Cliente:


    public partial class Cliente
    {
        public Cliente()
        {
            this.Pedido = new HashSet();
        }

        public int IdCliente { get; set; }
        public string Nombre { get; set; }
        public System.DateTime FechaNacimiento { get; set; }

        public virtual ICollection Pedido { get; set; }
    }

Investigando el modelo

La mejor forma de navegar a través de nuestro modelo es con el explorador de modelo o Model Browser. Por defecto no se muestra, por lo que para acceder a él, habrá que pulsar click derecho sobre el modelo y seleccionar la opción Model Browser.

En este explorador se nos mostrará que por un lado tenemos el modelo objetual y por otro, el relacional.

Siempre podemos añadir nuevos objetos desde la base de datos. Por ejemplo, si queremos añadir una vista y varios procedimientos almacenados, haremos click derecho sobre la parte relacional y seleccionaremos la opción Update Model from Database…

Acto seguido, seleccionamos los objetos que queremos mapear a objetos.

Finalmente aparecerán en el modelo, colocados en su carpeta correspondiente.

Desde el explorador podemos acceder a las propiedades de los modelos, y realizar operaciones como pluralizar las colecciones, tal y como sugerimos antes.

En caso de que no se cumpla, recordemos que toda entidad debe tener una clave de entidad. Sin ella, Entity Framework no será efectivo. El explorador del modelo también nos permitirá realizar esta operación.

Renombramos a plural también los elementos del Contexto, para dejar claro que se trata de colecciones

Si queremos accede a los detalles del mapeado, también es posible hacer click derecho sobre la entidad a consultar y pulsar click derecho sobre ella, seleccionando a continuación “Table Mapping”

Esto mostrará la información del mapeo, comparando columna y propiedad. Desde esta ventana podemos realizar operaciones como cambiar el mapeo o añadir ciertas condiciones.

Accediendo al modelo

Acceder al modelo es similar a lo que ya vimos con LINQ to SQL. Comenzaremos instanciando un DbContext (estará definido en el fichero <nombreModelo>.Context.cs), al que podemos pasar un parámetro de configuración como una cadena de conexión o bien dejarlo en blanco para que utilice la conexión por defecto.

A continuación lanzaremos una consulta mediante LINQ y recorreremos los elementos, tal y como vimos que se hacía en LINQ to SQL.


            // Instanciamos el contexto
            var contexto = new testdbEntities();

            // Lanzamos una consulta
            var clientes = from cliente in contexto.Clientes
                           select cliente;

            // Recorremos los clientes
            foreach (Cliente cliente in clientes)
            {
                Console.WriteLine(string.Format("ID: {0}\tNOMBRE: {1}\tAÑO NAC: {2}",
                    cliente.IdCliente, cliente.Nombre, cliente.FechaNacimiento.Year));

                // Recorremos los pedidos
                foreach (Pedido pedido in cliente.Pedidos)
                {
                    Console.WriteLine(string.Format("\tPEDIDO: {0}\tFECHA: {1}",
                        pedido.IdPedido, pedido.FechaPedido));

                    // Recorremos las líneas de pedido
                    foreach (LineaPedido linea in pedido.LineasPedido)
                    {
                        Console.WriteLine(string.Format("\t\tPRODUCTO: {0}\tCANTIDAD: {1}\tTOTAL: {2}",
                            linea.Producto.Descripcion, linea.Cantidad, (linea.Producto.Precio*linea.Cantidad)));
                    }
                }
                Console.WriteLine(" -----------------------------------------\n");
            }

Hecho esto, vemos que el acceso es correcto y que nuestro modelo funciona correctamente.

One comment

  1. Hola, gracias por tus aportes, son de muy buena calidad.

    Todo el artículo ya lo he implementado con VS2013 Community + EF5 + MySQL, pero con VS2015 + EF6 + MySQL no he podido.

    El error que me marca es el siguiente:

    “Su proyecto hace referencia a la versión mas reciente de Entity Framework; sin embargo, no se encuentra un proveedor de base de datos de Entity Framework compatible con esta versión para la conexión de datos.

    Si ya ha instalado un proveedor compatible, aseguresé de recompilar el proyecto antes de realizar esta acción. De lo contrario, salga de este asistente, instale un proveedor compatible y recompile el proyecto anntes de realizar esta acción.”

    Realizo los pasos establecidos en la siguiente URL proporcinada por el asistente

    https://msdn.microsoft.com/en-us/data/jj730568

    Sin embargo me sigue mostrando el mismo error.

    Te agradecería mucho si me pudieras orientar.

    Saludos…

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s