marcos de desarrollo - sabia.tic.udc.essabia.tic.udc.es/docencia/mad/pdf/03.02_entity... ·...

Post on 11-Mar-2018

232 Views

Category:

Documents

7 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Marcos de Desarrollo Diseño e implementación de aplicaciones Web con .NET

Objetivos

Conocer los componentes del Entity Framework y su funcionamiento

Saber crear un modelo de datos en Entity Framework

Aprender a realizar consultas sobre el modelo de datos en Entity SQL y LINQ to Entities

Conocer una implementación de un DAO Genérico implementado con Entity Framework

Introducción Entity Framework Programar contra un modelo, no contra la BB.DD.

EF evita pensar en la estructura de la BB.DD.

Acceso a datos y almacenamiento se hacen contra modelo conceptual

EF usa Entity Data Model (EDM)

Con tecnologías anteriores (DataReaders, DataSets) es necesario

escribir código de acceso a datos y transformar estos datos en objetos del dominio

EF permite recuperar directamente objetos del dominio y persistir los cambios cuando es necesario

Introducción Entity Framework Entity Data Model (EDM)

Es un modelo de datos del lado del cliente

Es el núcleo del EF

Esquema de un conjunto típico de tablas en BB.DD.

Introducción Entity Framework Entity Data Model (EDM)

Consulta T-SQL para recuperar registros de SalesPerson, junto con sus detalles personales

SELECT SalesPerson.*, PersonalDetails.*, Person.* FROM Person INNER JOIN PersonalDetails ON Person.PersonID = PersonalDetails.PersonID INNER JOIN SalesPerson ON Person.PersonID = SalesPerson.PersonID

Introducción Entity Framework Entity Data Model (EDM)

Datos de persona modelados para encajar con los objetos de dominio

Introducción Entity Framework Entity Data Model (EDM)

Consulta sobre objetos del dominio que devolverá un conjunto de objetos SalesPerson

from p in People.OfType<SalesPerson> select p

Introducción Entity Framework Entity Data Model (EDM)

Los ítems descritos por un EDM se conocen como entidades o entities.

Las clases generadas a partir de las entidades se conocen como clases de entidad (entity classes) y sus instancias objetos de entidad (entity objects).

Tienen propiedades, pero no comportamiento (salvo seguimiento de cambios). Equals(), toString(), getHashCode()

Introducción Entity Framework Entities

Diagrama de clases de entidad

Introducción Entity Framework Entities

El API de SqlClient incluida en VS 2008 SP1 y VS 2010 soporta EF

Se puede usar SQL Server 2005 y 2008 (full y Express)

SQL Server CE versión 3.5 y superiores también soportan EF

Hay más proveedores disponibles, que permiten usar Oracle,

IBM databases, SQL Anywhere, MySQL, SQLite, VistaDB y muchas otras Pueden ser desarrollados por los propios vendedores de BB.DD. o

por terceros Lista de proveedores proporcionada por MS:

http://msdn.microsoft.com/en-us/data/dd363565.aspx

Introducción Entity Framework Proveedores de Bases de Datos

Además del EDM, Entity Framework proporciona una serie de APIs y herramientas Metadatos

Herramientas de Diseño del EDM

Object Services

Seguimiento de cambios

Gestión de las relaciones y claves foráneas

EntityClient

Introducción Entity Framework Características principales

Metadatos

El modelo de datos conceptual se almacena en fichero XML

Este fichero también guarda una definición del esquema de la BD y las relaciones con el modelo conceptual

EF es capaz de traducir consultas sobre el modelo a consultas sobre la BD y transformar los resultados obtenidos a objetos del modelo, consultado estos metadatos

Introducción Entity Framework Características principales

Herramientas de diseño del EDM

EDM designer: permite trabajar con el modelo de entidades de forma visual, sin necesidad de tener que manipular el XML

Soporta las características más usadas

VS 2010 muchas más características que VS 2008 SP1

Incluye EDM Wizard: permite generar un modelo a partir de una BD

existente (database first)

VS 2010 permite crear el modelo en el diseñador y generar el esquema de la BD de forma automática (si lo soporta el proveedor) (model first)

Generador de código: se generan clases de forma automática a partir del modelo

Introducción Entity Framework Características principales

Object Services Proporcionan clase EntityObject

Permiten "materializar" objetos a partir de resultados de consultas

contra el EDM, realizar seguimiento de cambios en esos objetos, gestionar relaciones entre objetos y guardar los cambios en BD

Introducción Entity Framework Características principales

Seguimiento de cambios (tracking)

Una vez que un objeto entidad ha sido instanciado, los

Servicios de Objeto pueden realizar seguimiento de este objeto

Los Servicios de Objeto usan esta información a la hora

de actualizar los datos Construyen comandos Insert, Update, y Delete para cada

objeto que ha sido añadido, modificado o borrado, comparando los valores originales con los valores actuales.

Introducción Entity Framework Características principales

Gestión de Relaciones y Claves Foráneas

EF 4 incorpora soporte para claves foráneas

En un modelo ER clásico, las claves foráneas no se exponen en el modelo conceptual

La primera versión de EF (.NET 3.5 SP1) seguía este paradigma, pero ante la demanda de los desarrolladores se incorporó a la nueva versión

Introducción Entity Framework Características principales

Entity Client

Proporciona funcionalidad para realizar consultas, ejecutar comandos, recuperar resultados

Se puede trabajar con EntityClient directamente o a través de Object Services

Directamente, se obtienen resultados "tabulares"

A través de Object Services, se obtienen objetos

Introducción Entity Framework Características principales

¿Qué ocurre con DataSets y DataReaders?

Se pueden seguir usando

EF usa DR, en la forma de EntityDataReader, que extiende a DbDataReader (es lo que devuelve una consulta EntityClient)

Se recomienda no integrar las dos tecnologías (EF y DS/DR)

EF encajará mejor en unos proyectos y DS o DR en otros

Marcos de Desarrollo Diseño e implementación de aplicaciones Web con .NET

¿Por qué usar un EDM? BB.DD. se diseñan para ser mantenibles, seguras, eficientes

y escalables

Datos se organizan según principios de diseño de BB.DD.

OK desde el punto de vista de los datos, pero reto para el desarrollador que necesita acceder a ellos

Con EDM los desarrolladores se pueden concentrar en objetos de negocio

No hay que preocuparse por la estructura de la BD, nombres de las tablas o vistas, etc.

No hay que transformar los datos devueltos a objetos

Características del EDM del Entity Framework Genera clases de forma automática a partir del modelo y

las actualiza dinámicamente cuando el modelo cambia

Gestiona de la conectividad con la B.D.

Proporcionan sintaxis común para realizar consultas sobre el modelo Traduce estas consultas en otras comprensibles por la B.D.

Proporciona mecanismo para realizar seguimiento de

cambios en los objetos del modelo y soporta la actualización de éstos en B.D.

Pasos para crear un EDM (1 de 8) 1. Crear un proyecto de consola

2. Añadir nuevo ítem

Botón derecho sobre el nombre del proyecto > Add > New Item

Pasos para crear un EDM (2 de 8) 3. Seleccionar ADO.NET Entity Data Model

Pasos para crear un EDM (3 de 8) 4. Seleccionar "Generate from database“

Pasos para crear un EDM (4 de 8)

5. Seleccionamos una conexión

previamente configurada (p.

ej. desde VS) o creamos una

nueva.

Pasos para crear un EDM (5 de 8)

Pasos para crear un EDM (6 de 8)

La cadena de conexión se guardará

en el archivo de configuración del

proyecto (App.Config).

Nombre por defecto:

<Nombre_BD> + Entities

Es también el nombre que se le

dará al contenedor de entidades.

Pasos para crear un EDM (7 de 8)

6. Seleccionamos los objetos de

base de datos que queremos

incluir en el modelo

Nombre por defecto del modelo:

<Nombre_BD> + Model

Pasos para crear un EDM (8 de 8)

Pasos para crear un EDM (8 de 8)

Entity Data Model (EDM)

• Archivo con extensión .edmx

• XML, aunque por defecto se

muestra de forma gráfica Entidades (Entities)

Lo veremos más

adelante

Propiedades del Entity Container

botón derecho >

Properties

Propiedades de las entidades

sobre el nombre de la

entidad

el nombre de la entidad

siempre debe ser singular

Propiedades de las entidades

sobre el nombre de la

entidad

Propiedades de navegación

Propiedades de navegación

Propiedades de navegación

Metadatos del modelo En el Diseñador sólo se ve la parte conceptual del

modelo, pero hay más secciones críticas del EDMX: StorageModels y Mappings

Componentes de los metadatos del modelo del EF

.csdl: Conceptual Schema Definition Language

.ssdl: Store Schema Definition Language

.msl: Mapping Specification Language

Vista del modelo en "Model Browser"

Se puede acceder desde el menú contextual de la superficie de diseño del modelo.

Permite ver:

CSDL

SSDL

Vista de los "mappings" Desde el menú contextual de la superficie de diseño

del modelo > "Mapping Details"

Enlaces entre los campos de la tabla Account y las propiedades de la Entidad Account

Vista del modelo en formato XML Por defecto, el fichero .edmx se abrirá en el Diseñador.

Para ver el contenido XML, desde "Solution Explorer", sobre el nombre del archivo, botón derecho > Open With > XML Editor

Asistente de actualización del EDM

Permite actualizar el modelo EDM después de que se hayan realizado cambios en la BD

Desde el menú contextual de la superficie de diseño del modelo > "Update from database"

Marcos de Desarrollo Diseño e implementación de aplicaciones Web con .NET

Formas de consultar el EDM

LINQ to Entities

Entity SQL

Métodos especiales basados en LINQ

basados en la clase ObjectQuery

EntityClient

Arquitectura y componentes

Componentes de la arquitectura de EF

Una consulta sencilla Usando tipado implícito

static void Main(string[] args)

{

using (var context = new TestEntities())

{

var accounts = context.Accounts;

foreach (var account in accounts)

{

Console.WriteLine("Acc ID: {0}, Balance: {1}",

account.accId, account.balance);

}

}

}

Una consulta sencilla Usando tipado explícito

static void Main(string[] args)

{

using (TestEntities context = new TestEntities())

{

ObjectSet<Account> accounts = context.Accounts;

foreach (Account account in accounts)

{

Console.WriteLine("Acc ID: {0}, Balance: {1}",

account.accId, account.balance);

}

}

}

Generación de código basado en el modelo El Diseñador del EDM genera

automáticamente código basado en el modelo

El código generado se almacena en un archivo .Designer.cs

Lee la capa conceptual del modelo y crea a partir de ella una clase ObjectContext (TestEntities en el ej.) basada en el EntityContainer, y luego una clase entidad para cada entidad en el modelo (Account y AccountOp en el ejemplo)

ObjectContext y clases entidad

Consultas con LINQ to Entities (1 de 3) Ej.: consultar cuenta con accID = 1

using (TestEntities context = new TestEntities())

{

var accounts = from a in context.Accounts

where a.accId == 1

select a;

foreach (Account account in accounts)

{

Console.WriteLine("Acc ID: {0}, Balance: {1}",

account.accId, account.balance);

}

}

Consultas con LINQ to Entities (2 de 3) Ej.: consultar número de cuentas de un usuario

using (TestEntities context = new TestEntities()) { int result = (from acc in context.Accounts where acc.usrId == userId select acc).Count(); Console.WriteLine(result); }

Consultas con LINQ to Entities (3 de 3) Ej.: Ej.: recuperar las cuentas de un usuario

(implementando Page-by-Page)

using (TestEntities context = new TestEntities())

{

List<Account> accounts =

(from a in context.Accounts

where a.usrId == userId

orderby a.accId

select a).Skip(startIndex).Take(count).ToList();

foreach (Account account in accounts)

{

Console.WriteLine("Acc ID: {0}, Balance: {1}",

account.accId, account.balance);

}

}

Consultas con Object Services y Entity SQL (1 de 3) Ej.: consultar cuenta con accID = 1

using (TestEntities context = new TestEntities())

{

var queryString = "SELECT value a " +

"FROM TestEntities.Accounts AS a " +

"WHERE a.accID = 1";

ObjectQuery<Account> accounts = context.CreateQuery<Account>(queryString);

foreach (Account account in accounts)

{

Console.WriteLine("Acc ID: {0}, Balance: {1}",

account.accId, account.balance);

}

}

Consultas con Object Services y Entity SQL (2 de 3) Ej.: consultar número de cuentas de un usuario

using (TestEntities context = new TestEntities())

{

String query = "SELECT VALUE a FROM Accounts AS a " +

"WHERE a.usrId = @userId";

ObjectParameter param = new ObjectParameter(“userId", userId);

int result =

context.CreateQuery<Account>(query, param).Count();

Console.WriteLine(result);

}

Consultas con Object Services y Entity SQL (3 de 3) Ej.: recuperar las cuentas de un usuario

(implementando Page-by-Page)

using (TestEntities context = new TestEntities())

{

String query = "SELECT VALUE a FROM Accounts AS a " +

"WHERE a.usrId = @userId " +

"ORDER BY a.accId";

ObjectParameter param = new ObjectParameter("userId", userId);

List<Account> accounts = context.CreateQuery<Account>(query, param)

.Skip(startIndex).Take(count).ToList();

foreach (Account account in accounts)

{

Console.WriteLine("Acc ID: {0}, Balance: {1}",

account.accId, account.balance);

}

}

LINQ vs. Entity SQL

Entity SQL Se creó antes que LINQ

Disponible para todos los lenguajes de la plataforma

Permite trabajar a nivel más "bajo" que LINQ (sin pasar por Object Services)

LINQ Variantes (LINQ XML, LINQ to Objects, …)

Tipado fuerte

Sólo disponible en C# y VB.NET

Arquitectura y componentes

Componentes de la arquitectura de EF

Consultas sobre EntityClient static void EntityClientQuery() { using (EntityConnection c = new EntityConnection(“name=SampleEntities”)) { c.Open(); string queryString = “select value c from SampleEntities.Contacts as C”; EntityCommand cmd = c.CreateCommand(); cmd.CommandText = queryString; using (EntityDataReader edr = cmd.ExecuteReader()) { while (edr.Read()) { string name = edr.GetString(1); string surName = edr.GetString(2); Console.WriteLine(“{0}, {1}”, surname, name); } } c.Close(); } }

Marcos de Desarrollo Diseño e implementación de aplicaciones Web con .NET

Implementación de DAOs con Entity Framework DAO genérico con las operaciones comunes a todas las clases persistentes:

Create, Find, Exists, Update, Remove

Cada entidad persistente tendrá su propio DAO, que extenderá el genérico para añadir operaciones propias

El DAO genérico se encuentra en el proyecto ModelUtil

ModelUtil es utilizado por MiniBank y MiniPortal

Es de tipo "Librería de clases" (.dll)

La interfaz parametrizada del DAO genérico recibe 2 argumentos:

E, es la clase persistente para la que se implementará el DAO

PK, define el tipo del identificador de la clase persistente

Los métodos están definidos en base a esos parámetros y no están acoplados a ninguna tecnología de persistencia

Implementación de DAOs con Entity Framework Interfaz del DAO genérico

public interface IGenericDao<E, PK>

{

void Create(E entity);

/// <exception cref="InstanceNotFoundException"></exception>

E Find(PK id);

Boolean Exists(PK id);

void Update(E entity);

/// <exception cref="InstanceNotFoundException"></exception>

void Remove(PK id);

}

Implementación de DAOs con Entity Framework Implementación del DAO genérico con Entity Framework

public class GenericDaoEntityFramework<E, PK> :

IGenericDao<E, PK> where E : IEntityWithKey

{

// entityClass is set in the constructor of this class

private Type entityClass;

// context must be set by means of Context property

private ObjectContext context;

private String entityContainerName;

public GenericDaoEntityFramework()

{

this.entityClass = typeof(E);

}

Implementación de DAOs con Entity Framework Implementación del DAO genérico con Entity Framework

[Dependency] public ObjectContext Context { set { // The value of the Context property is established context = value; entityContainerName = (context.MetadataWorkspace. GetItems<EntityContainer>(DataSpace.CSpace))[0].Name; context.DefaultContainerName = entityContainerName; // Forces the load of the metadata context.MetadataWorkspace.LoadFromAssembly( entityClass.Assembly); } get { return context; } }

Inyección de Dependencias

(lo veremos + adelante)

Implementación de DAOs con Entity Framework Implementación del DAO genérico con Entity Framework

/// <summary>

/// Creates the entity key. It is needed to get primary key field name

/// from metadata.

/// </summary>

public EntityKey CreateEntityKey(PK id) { EntityType entityType = (EntityType)context.MetadataWorkspace.GetType(entityClass.Name, entityClass.Namespace, DataSpace.CSpace); /* We assume that the DAO works only with single field primary * key classes */ String primaryKeyFieldName = ((EntityType)entityType).KeyMembers.First().ToString(); // Create the entityKey EntityKey entityKey = new EntityKey(GetQualifiedEntitySetName(entityClass.Name), primaryKeyFieldName, id); return entityKey; }

Implementación de DAOs con Entity Framework Implementación del DAO genérico con Entity Framework

/// <summary>

/// Returns the qualified EntitySet name (the EntityContainer name plus

/// the EntitySet name) for a given entityClassName.

/// </summary>

/// <param name="entityClassName">Type name of an entity</param>

/// <returns>The Qualified EntitySet name</returns>

public String GetQualifiedEntitySetName(String entityClassName)

{

EntityContainer container = context.MetadataWorkspace.

GetEntityContainer(context.DefaultContainerName,

DataSpace.CSpace);

EntitySetBase entitySet = container.BaseEntitySets.Where(item =>

item.ElementType.Name.Equals(entityClassName)).FirstOrDefault();

return (entityContainerName + "." + entitySet.Name);

}

Implementación de DAOs con Entity Framework Implementación del DAO genérico con Entity Framework

public void Create(E entity) {

/* Adds the object to the object context. The entity's EntityState

* will be set to Added. Therefore, when SaveChanges is called, it

* will be clear to the Entity Framework that this entity needs to

* be inserted into the database.

*/

context.AddObject(GetQualifiedEntitySetName(entityClass.Name), entity);

/* Persists back to the database all of the changes made to

* the entities. By default, the SaveChanges method calls the method

* AcceptAllChanges after it has performed the database

* modifications. AcceptAllChanges pushes the current values of

* every attached entity into the original values and then changes

* their EntityState to Unchanged.

*/

context.SaveChanges();

}

Implementación de DAOs con Entity Framework Implementación del DAO genérico con Entity Framework

/// <exception cref="InstanceNotFoundException"/> public E Find(PK id) { EntityKey entityKey = this.CreateEntityKey(id); try { E result = (E)context.GetObjectByKey(entityKey); return result; } catch (ObjectNotFoundException) { throw new InstanceNotFoundException(id, entityClass.FullName); } }

Implementación de DAOs con Entity Framework Implementación del DAO genérico con Entity Framework

public Boolean Exists(PK id) { Boolean objectFound = true; EntityKey entityKey = this.CreateEntityKey(id); try { object result = context.GetObjectByKey(entityKey); } catch (ObjectNotFoundException) { objectFound = false; } return objectFound; }

Implementación de DAOs con Entity Framework Implementación del DAO genérico con Entity Framework

public E Update(E entity) { // Last Updates are sent to database context.Refresh(RefreshMode.ClientWins, entity); context.SaveChanges(); }

Implementación de DAOs con Entity Framework Implementación del DAO genérico con Entity Framework

/// <exception cref="InstanceNotFoundException"/> public void Remove(PK id) { E objectToRemove = default(E); try { // First we need to find the object objectToRemove = Find(id); context.DeleteObject(objectToRemove); context.SaveChanges(); } catch (InstanceNotFoundException) { throw; }

Implementación de DAOs con Entity Framework Implementación del DAO genérico con Entity Framework

catch (OptimisticConcurrencyException) { context.Refresh(RefreshMode.ClientWins, objectToRemove); context.DeleteObject(objectToRemove); context.SaveChanges(); } catch (InvalidOperationException) { throw new InstanceNotFoundException(id, entityClass.FullName); } }

Implementación de DAOs con Entity Framework

Para implementar la persistencia utilizando Entity Framework, el DAO necesita un objeto ObjectContext Se asigna y recupera a través de la propiedad Context

Se utilizará inyección de dependencias para establecer el valor de la propiedad Context

Para implementar las operaciones se puede elegir EntitySQL o Linq-to-Entities

Implementación de DAOs con Entity Framework Ej.: MiniBank > AccountDao

AccountDaoEntityFramework

public List<Account> FindByUserId(long userId, int startIndex,

int count)

{

ObjectSet<Account> accounts = Context.CreateObjectSet<Account>();

var result =

(from a in accounts

where a.usrId == userId

orderby a.accId

select a).Skip(startIndex).Take(count).ToList();

return result;

}

Implementación de DAOs con Entity Framework Ej.: MiniBank > AccountOperationDao

Bibliografía Recomendada:

J. Lerman. Programming Entity Framework. 2nd edition. O'Reilly. 2010.

top related