Capitulo 6 - ADO.NET Entity Framework (Parte 1)

Lección 1: ¿Qué es ADO.NET Entity Framework?
Al escribir aplicaciones orientadas a objetos,a veces es necesario algún medio para la persistencia de los objetos, esto normalmente significa la creación de un modelo de datos que represente a la base de datos relacional. Entity Framework puede proporcionar esto.
Descripción de la Arquitectura de Entity Framework
Entity Framework permite a las aplicaciones acceder y modificar los datos como si fueran entidades y relaciones. Entity Framework convierte las consultas de objetos descritas en el modelo conceptual en las consultas de base de datos mediante el uso de la información en el modelo y los archivos de mapeo.
clip_image001[4]

Se puede consultar un modelo conceptual y devolver objetos mediante el uso de LINQ to Entities o Entity SQL (ESQL). ESQL es un dialecto de almacenamiento independiente de SQL que trabaja directamente con las entidades del modelo conceptual, este permite realizar consultas de objetos y consultas que se ejecutan mediante el proveedor de EntityClient.
La capa de servicios de objetos (Object Services) es un componente de Entity Framework que permite consultar, insertar, actualizar y eliminar datos, utilizando Common Language Runtime (CLR).
La capa de servicios de objetos es la responsable de crear instancias de los datos devueltos como objetos, y propaga los cambios de objeto a la fuente de datos. Es implementada por las clases en el System.Data.Objects y los espacios de nombres System.Data.Objects.DataClasses.
Entity Framework vs LINQ to SQL
La siguiente tabla proporciona una referencia rápida de las principales diferencias entre las dos tecnologías.
Categoria
Linq to SQL
Entity Framework
Complejidad
menos complejo
mas complejo
Modelo
modelo del dominio
modelo de datos conceptual
DB Server
SQL Server
Variedad de productos de base de datos
Tiempo de Desarrollo
Desarrollo de aplicaciones rápido
más tiempo, pero tiene características de modo
Tipo de mapeo
de una clase a una sola tabla
de una clase a varias tablas
Herencia
Difícil de aplicar
Fácil de aplicar
Tipos de archivos
DBML
EDMX, CDSL, MSL, SSDL
Tìpos complejos
no
si
Capacidad de consulta
LINQ to SQL mediante DataContext
LINQ to Entities, ESQL, Object Services, Entity Client
Performance
Lenta para la primera consulta
Lenta para la primera consulta, pero en general mejor que LINQ to SQL
Mejoras en el futuro
No
Si
Genera el modelo de la DB
No
Si
Modelando datos Para usar el Entity Framework, es necesario crear una entidad de modelo de datos con sus clases y su mapeo en el esquema de base de datos. Después se pueden realizar operaciones CRUD (crear, recuperar, actualizar y eliminar).
Escenarios de mapeo
Para crear un modelo de datos de la entidad, debe tener un conocimiento básico de los escenarios de asignación soportados por Entity Framework.
Escenario de mapeo (también llamado asignación)
Descripción
Mapeo simple
Cada entidad en el modelo conceptual se mapea a una única tabla.
División de entidad
Las propiedades de una única entidad en el modelo conceptual se asignan a las columnas de dos o más tablas en la base. En este escenario, las tablas deben compartir una clave principal común.
mas info en: Cómo: Definir un modelo con una única entidad asignada a dos tablas.
Particiones horizontales en el modelo conceptual
Varios tipos de entidad en el modelo conceptual que tienen las mismas propiedades se mapean a una única tabla. Se usa una cláusula de condición para especificar los datos de la tabla que pertenecen a cada tipo de entidad.
Cómo: Definir un modelo con herencia de tabla por jerarquía.
Herencia de tabla por jerarquía
Todos los tipos de una jerarquía de herencia se mapean a una única tabla. Una cláusula de condición se utiliza para definir los tipos de entidad. 
Cómo definir un modelo con herencia de tabla por jerarquía (Entity Framework).
Herencia de tabla por tipo
Todos los tipos se asignan a tablas individuales.
Cómo: Definir un modelo con herencia de tabla por tipo (Entity Framework).
Herencia de tabla por tipo concreto
Cada uno de los tipos no abstractos se asigna a una tabla individual.
Varios conjuntos de entidades por tipo
Un solo tipo de entidad se expresa en dos o más conjuntos de entidades independientes en el modelo conceptual. Cada conjunto de entidades se asigna a una tabla independiente.
Cómo: Definir un modelo con múltiples conjuntos de entidades por tipo (Entity Framework).
Tipos complejos
Es una propiedad no escalar de un tipo de entidad que no tiene una propiedad clave. Un tipo complejo puede contener otros tipos complejos anidados. Los tipos complejos se asignan a las tablas en el modelo de almacenamiento. 
How to: Create and Modify Complex Types.
Mapeo de importación de función
Un procedimiento almacenado se mapea a un elemento FunctionImport del modelo conceptual.
Cómo: Definir un modelo con un procedimiento almacenado (Entity Framework).
Mapeo de función de modificación
Los procedimientos almacenados se definen en el modelo de almacenamiento para insertar, actualizar y eliminar los datos para cada tipo de entidad.
Cómo definir un modelo con procedimientos almacenados de modificación (Entity Framework).
Definir el mapeo de una consulta
La consulta se expresa en el lenguaje de consultas nativo del origen de datos, como Transact-SQL al asignar a una base de datos de SQL Server. Este elemento DefiningQuery se asigna a un tipo de entidad en el modelo conceptual.
How to: Add a Defining Query.
Mapeo de vistas de consulta
Una asignación de solo lectura se define entre los tipos de entidad del modelo conceptual y las tablas relacionales del modelo de almacenamiento.
QueryView (Elemento) (MSL).
Mapeo AssociationSet
Las asociaciones definen las relaciones entre las entidades. En una asignación simple con una asociación uno a uno o uno a varios, las asociaciones que definen las relaciones en el modelo conceptual se asignan a las asociaciones en el modelo de almacenamiento. También se admiten las siguientes asignaciones más avanzadas de conjuntos de asociaciones:
· Asociaciones varios a varios. Ambos extremos de la asociación se asignan a una tabla de vínculos en el modelo de almacenamiento.
· Auto-asociación. Admite una asociación entre dos entidades del mismo tipo, como un empleado con una asociación a otro empleado.
Code First Model vs. Database First Model
¿Que significa Code First Model?
Es cuando se crea un modelo conceptual antes de crear la base de datos. Se puede generar la base de datos a partir del modelo conceptual, pero primero tienes que crear un modelo conceptual de forma manual.
¿Que es el Database First Model ?
Esto permite generar el modelo conceptual a partir de la base de datos, pero primero hay que crear el esquema de base de datos manualmente.
Implementando Code First Model
Para utilizar el modelo de Código En primer lugar, se debe agregar un archivo ADO.NET Entity DataModel.edmx al proyecto,
clip_image002[4]clip_image003[4]
Seleccionar Empty Model,
clip_image004[4]
Utilizar la barra de herramientas de arrastrar y soltar una entidad que en el diseñador de Entity Data Model. Se puede hacer clic en el nombre y escribir uno nuevo.En cada entidad se deben agregar las propiedades respectivas.
clip_image005[4]
Cuando se hace clic en una entidad se muestran sus propiedades en la ventana Propiedades:
clip_image006[4]
·                     Abstract: determina si la entidad es abstracta. Se establece esta propiedad a true cuando la entidad se van a derivar otras entidades, y no se quiere una instancia de esta entidad directamente.
·                     Access: establece el nivel de acceso del tipo.Public o Internal.
·                     Base Type: permite establecer la entidad de la que esta entidad será derivada.
·                     Documentation: permite introducir comentarios XML. El resumen y los elementos longDescription son compatibles..
·                     Entity Set Name: el nombre del entityset que contiene las entidades.
·                     Name: nombre de la entidad.

Al hacer clic en cada una de las propiedades de la entidad se muestran en la ventana Propiedades.
clip_image007[4]
·                     Concurrency Mode: None de forma predeterminada, significa que no se mantienen bloqueos sobre los datos del origen de datos desde que se consultan hasta que son actualizados. Entity Framework guarda los cambios de los objetos en la base de datos sin comprobar la simultaneidad. Para entidades que pudieran experimentar un alto grado de simultaneidad, se debe colocar esta propiedad  en fixed.
·                     Default value: valor inicial de la propiedad.
·                     Entity Key: si es primary key.
·                     Getter: establece el modificador de acceso para el getter. Los valores son internos, privados, protegidos y públicos.
·                     Name: nombre de la propiedad.
·                     Nullable: si puede contener valores nulos
·                     setter:establece el modificador de acceso para el setter.
·                     StoreGeneratePattern: permite indicar si el valor de la propiedad se genera automáticamente.
o                  None: no se autogenera.
o                   Identity: indica que este valor será una columna de numeración automática .inserción.
o                  Computed: la propiedad es calculada después de insertar o modificar.
·                     Type: tipo de datos de la propiedad.
Para demostrar que dos tablas están relacionadas, se puede establecer una asociación desde la barra de herramientas eligiendo la Asociación, y seleccionando la entidad madre y luego la entidad hija. Para setear sus propiedades se debe hacer clic en la asociación.
Una vez que el modelo conceptual está completo, se puede generar la base de datos haciendo clic en la superficie del diseñador de Entity Framework y eligiendo Generar bases de datos desde el modelo. Este solicita una conexión de base de datos, y se debe hacer clic en Nueva conexión.
clip_image008[4]
Se necesita configurar la conexión a un servidor de base de datos y escribir el nombre de la nueva base de datos. Después de crearla, aparece el DDL (Data Definition Language) y el nombre del archivo. El script se ha creado y guardado en un archivo, pero no se ha ejecutado. Para ejecutar el script, se puede hacer clic derecho en la ventana del script abierto, y clic en Ejecutar SQL. Solicita una conexión de base de datos, y luego ejecuta el script.
Para cambiar el esquema de base de datos, se puede hacer clic en el diseñador y así establecer las propiedades generales del modelo conceptual.
·                     Code Generation Strategy  generación del código de los objetos on o off.
·                     Database Generation Workflow:  ruta del archivo de Windows Workflow Foundation donde se va crear la base de datos que utiliza el Asistente para modelos. Se puede copiar y modificar el archivo existente para cambiar el comportamiento de la generación de la bases de datos.
·                     Database Schema Name: nombre del esquema al que todos los objetos de base de datos generada se añaden. El valor predeterminado es dbo. Si cambia el nombre a uno que no existe, el esquema se crea automáticamente cuando se genera la base de datos.
·                     DDL Generation Template: nombre de la plantilla texto T4 que transforma  el SSDL (del modelo) a DDL para generar bases de datos desde el Asistente.
·                     Entity Container Access: modificador de acceso del contenedor de entidades, puede ser público o interno
·                     Entity Container Name: nombre del contenedor creado para alojar todas las instancias de las entidades. Esta clase se deriva de la clase ObjectContext.
·                     Lazy Loading Enabled: Se establece  esta propiedad en true para realizar la carga de los datos just–in-time (justo a tiempo) .
·                     Metadata Artifact Processing: Esta propiedad establece si el modelo y los archivos de asignación (Mapeo) (.csdl, .ssdl, y.msl) están incrustados en el ensamblado (por defecto) o se copian en el directorio de salida.
·                     Namespace: espacios de nombres XML del modelo conceptual.
·                     Pluralize New Objects: especifica si los nuevos nombres de las entidades y las propiedades de navegación son en plural. Valor predeterminado es true.
·                     Transform Related Text Templates On Save: Una plantilla de texto está relacionado con un archivo. Edmx mediante la inserción del nombre del archivo EDMX en la plantilla de texto. Cuando se establece en true (por defecto), todas las plantillas se procesan cuando el archivo se guarda EDMX, de lo contrario no se procesan.
·                     Validate On Build: especifica si el modelo se valida cuando el proyecto se ha generado. Valor predeterminado es true.
Implementando Database First Model
Pasos a seguir:
1.            En el Solution Explorer, clic derecho --> seleccione Add --> New Item
2.            En la ventana de dialogo de Add New Item --> Data -->ADO.NET Entity Data Model.
3.            se debe colocar el nombre, en este caso NorthwindModel.edmx --> Add.
4.            En la ventana para elegir el contenido del modelo --> Generate from database. clip_image009[4]
5.            escribir la Data Connection--> seleccionamos las tablas que queremos tener en el modelo --> Finish.
clip_image010[4]  clip_image011[4]
clip_image012[3]
Modelo Generado
clip_image013[3]
Algunas asociaciones tienen una relación uno-a-muchos, mientras que otras asociaciones tienen una relación uno a cero a uno-a-muchos. Esto varía en función de si la clave externa permite valores nulos.
Las tablas CustomerCustomerDemo y EmployeeTerritories no se muestran  en el modelo conceptual, porque estas existen simplemente para poner en práctica la relación de muchos a muchos.
Claves y relaciones Si nos fijamos en la ventana Propiedades de una asociación,  se pueden ver las siguientes propiedades:
Association Set Name: nombre de la tabla implementada para llevar a cabo una relación de muchos a muchos o el nombre de la relación que une a las tablas en una relación uno-a-muchos.
Documentation: comentarios XML
End1 Multiplicity : numero de entidades en el final de la asociación (0, 0..1 o * (muchos)).
End1 Navigation Property : Especifica el nombre de la propiedad de navegación que devuelve los valores al final. Ej, si se establece esta propiedad a los clientes, habrá una propiedad en la entidad actual llamados clientes, se puede utilizar esta propiedad para recuperar una lista de clientes que se relacionan con la entidad actual.
End1 OnDelete : Especifica la acción a realizar en la eliminación de una entidad del extremo 1.
End1 Role Name nombre de la tabla a la que se unió a este extremo de la relación.
End2 Multiplicity numero de entidades en las que termina la asociación (0, 0..1 o * (muchos))
End2 Navigation Property: Especifica el nombre de la propiedad de navegación devuelve valores que en este extremo (el segundo).
End2 OnDelete : acción a realizar en la eliminación de una entidad del extremo 2. Los valores válidos son None, que no realizará ninguna acción de eliminación, o en cascada,
End2 Role Name nombre de la tabla en la que termina la asociación
Name nombre de la asociación
Referential Constraint : muestra la dirección de la relación

Administrando la conexión a la bases de datos y del contexto usando el ObjectContext
Recuperando datos con un ObjectContext
Después de crear nuestro modelo conceptual de Northwind, se ha creado la clase NorthwindEntities, que hereda de ObjectContext y esto nos permite recuperar datos con mucha facilidad. Por ej:
-------------------------------------VB-------------------------------------------
Private Sub UsingTheObjectContextToolStripMenuItem_Click( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles UsingTheObjectContextToolStripMenuItem.Click
Dim db As New NorthwindEntities()
gv.DataSource = (From c In db.Customers
Select New With
{
.CompanyID = c.CustomerID,
.CompanyName = c.CompanyName
}).ToList()
End Sub
-------------------------------------CS-------------------------------------------
private void usingTheObjectContextToolStripMenuItem_Click(
object sender, EventArgs e)
{
var db = new NorthwindEntities();
gv.DataSource = (from c in db.Customers
select new
{
c.CustomerID,
c.CompanyName
}).ToList();
}
¿Cómo se conecta Entity Framework a la base de datos?
Se conecta usando una clase que hereda de ObjectContext, para recuperar los datos mediante una consulta LINQ to Entities.
Ej del código fuente generado por el diseñador de Entity Framework para crear la clase NorthwindEntities:
-------------------------------------VB-------------------------------------------
Public Partial Class NorthwindEntities
Inherits ObjectContext
Public Sub New()
MyBase.New("name=NorthwindEntities", "NorthwindEntities")
MyBase.ContextOptions.LazyLoadingEnabled = true
OnContextCreated()
End Sub
Public Sub New(ByVal connectionString As String)
MyBase.New(connectionString, "NorthwindEntities")
MyBase.ContextOptions.LazyLoadingEnabled = true
OnContextCreated()
End Sub
Public Sub New(ByVal connection As EntityConnection)
MyBase.New(connection, "NorthwindEntities")
MyBase.ContextOptions.LazyLoadingEnabled = true
OnContextCreated()
End Sub
Public ReadOnly Property Categories() As ObjectSet(Of Category)
Get
If (_Categories Is Nothing) Then
_Categories = MyBase.CreateObjectSet(Of Category)("Categories")
End If
Return _Categories
End Get
End Property
Private _Categories As ObjectSet(Of Category)
Public Function CustOrderHist(customerID As Global.System.String) As ObjectResult(Of
CustOrderHist_Result)
Dim customerIDParameter As ObjectParameter
If (customerID IsNot Nothing)
customerIDParameter = New ObjectParameter("CustomerID", customerID)
Else
customerIDParameter = New ObjectParameter("CustomerID", GetType(Global.
System.String))
End If
Return MyBase.ExecuteFunction(Of CustOrderHist_Result)("CustOrderHist",
customerIDParameter)
End Function
End Class
-------------------------------------CS-------------------------------------------
public partial class NorthwindEntities : ObjectContext
{
public NorthwindEntities() : base("name=NorthwindEntities", "NorthwindEntities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}

public NorthwindEntities(string connectionString)
: base(connectionString, "NorthwindEntities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
public NorthwindEntities(EntityConnection connection)
: base(connection, "NorthwindEntities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
public ObjectSet<Category> Categories
{
get
{
if ((_Categories == null))
{
_Categories = base.CreateObjectSet<Category>("Categories");
}
return _Categories;
}
}
private ObjectSet<Category> _Categories;
public ObjectResult<CustOrderHist_Result> CustOrderHist(global::System.String
customerID)
{
ObjectParameter customerIDParameter;
if (customerID != null)
{
customerIDParameter = new ObjectParameter("CustomerID", customerID);
}
else
{
customerIDParameter = new ObjectParameter("CustomerID",
typeof(global::System.String));
return base.ExecuteFunction<CustOrderHist_Result>("CustOrderHist",
customerIDParameter);
}
}
}
En el código anterior se puede ver que hay 3 constructores:
1º: constructor sin parámetros, que llama al constructor de ObjectContext y pasa el nombre de la cadena de conexión almacenada en el archivo app.config o web.config y el nombre del contenedor de entidades que tiene por defecto.
2º: permite pasar una cadena de conexión explícita como un parámetro, que se pasa al constructor de ObjectContext.
3º: El constructor acepta la conexión actual y se la pasa al ObjectContext. Esto es útil cuando se está ejecutando una transacción local y queremos unirnos a una transacción en curso.
 
Los Proveedores y la cadena de conexión
Las cadenas de conexión contienen la información que se le pasa a un proveedor de datos para iniciar la conexión. La información de la cadena de conexión varía según el proveedor. Al trabajar con Entity Framework, las cadenas de conexión contienen la información para conectarse a la base de datos mediante el proveedor de ADO.NET.
La cadena de conexión también contiene información sobre los modelos y mapas que la clase EntityClient utiliza para acceder al modelo y los metadatos de mapeo cuando se conecta a la base de datos. Ejemplo de la conexión NorthwindEntities:
<add name="NorthwindEntities"
connectionString="metadata=res://*/NorthwindModel.csdl|
res://*/NorthwindModel.ssdl|
res://*/NorthwindModel.msl;
provider=System.Data.SqlClient;
provider connection string=&quot;
Data Source=.;Initial Catalog=Northwind;
Integrated Security=True;
MultipleActiveResultSets=True&quot;"
providerName="System.Data.EntityClient" />
En esta cadena de conexión, se encuentran las referencias de los metadatos. Csdl,.Ssdl, y los .Msl, que son recursos incrustados en el ensamblado compilado:
Metadata=res://<assemblyFullName>/<resourceName>.
AssemblyFullname es el nombre completo de un ensamblado con el recurso incrustado. Incluye el nombre, la versión, la cultural admitida, y la clave pública:
ResourceLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Se pueden  incorporar recursos en cualquier ensamblado que sea accesible por la aplicación. También se puede especificar un comodín (*) para AssemblyFullName, y Entity Framework búsquedara en tiempo de ejecución los recursos en los siguientes lugares,en este orden:
1. El ensamblado llamado
2. Los ensamblados referenciados
3. Los ensamblados en el directorio bin de una aplicación
Si los archivos no se encuentran en uno de estos lugares, se inicia una excepción.

No hay comentarios:

Publicar un comentario