SlideShare uma empresa Scribd logo
1 de 14
Baixar para ler offline
LINQ to SLQ (Parte 7 – Actualizando la base de datos con procedimientos almacenados) 
9 respuestas 
En las últimas semanas he escrito una serie de post sobre LINQ to SQL. Es un ORM integrado en .NET 3.5, y nos permite modelar bases de datos relacionales con clases de .NET. Podemos usar expresiones LINQ para consultar a la base de datos, actualiazarla, insertar y borrar datos. 
Aquí tenéis los enlaces a los otros post: 
 Parte 1: Introducción a LINQ to SQL 
 Parte 2: Definiendo el modelo de datos. 
 Parte 3: Consultando la base de datos 
 Parte 4: Actualizando la base de datos. 
 Parte 5: Enlazar controles de interfaz de usuario con el ASP:LinqDatSource 
 Parte 6: Obtener datos con procedimientos almacenados. 
En la sexta parte vimos cómo podemos usar procedimientos almacenados (SPROCs) y funciones definidas por el usuario (UDFs) para consultar la base de datos con el modelo de datos de LINQ to SQL. En el post de hoy veremos cómo podemos usar los SPROCs para actualizar/insertar/borrar datos de nuestra base de datos. 
Para ayudar a entender esto empezaremos costruyendo una capa de datos para la base de datos de ejemplo Northwind: 
Paso 1: Crear nuestra capa de acceso a datos (sin SPROCs) 
En la segunda parte de esta serie vimos cómo usar el diseñador de LINQ to SQL de VS 2008 para crear el siguiente modelo de clases:
Añadiendo reglas de validación a nuestro modelo de clases. 
Después de definir nuestro modelo querremos añadir reglas de validación a nuestro modelo de datos. Podemos hacer esto añadiendo clases parciales a nuestro proyecto y añadir las reglas de validación en esas clases (vimos cómo hacer esto en la cuarta parte de esta serie). 
Por ejemplo, podemos añadir la lógica necesaria para asegurarnos de que el número de teléfono de los clientes siguen un patrón válido, y otra para asegurarnos de que la fecha de entrega (RequierdDate) es posterior a la fecha actual del pedido (OrderDate). Una vez que hemos definido las clases parciales, estos métodos de validación se ejecutarán cada vez que escribamos código para actualizar nuestros objetos de datos de nuestra aplicación: 
VB:
C#:
Añadir un método de ayuda GetCustomer() a nuestro DataContext 
Una vez que hemos creado nuestro modelo de clases, y que le hemos añadido reglas de validación, podemos consultar e interactuar con los datos. Podemos hacer esto escribiendo expresiones LINQ sobre nuestro modelo de clases (vimos cómo hacer esto en la tercera parte de esta serie). También podemos mapear SPROCs en nuestro DataContext (esto lo vimos en la sexta parte de la serie). 
Cuando creamos una capa de datos con LINQ to SQL normalmente querremos encapsular consultas comunes de LINQ (o SPROCs) en métodos auxiliares que añadiremos a la clase DataContext. Esto lo conseguimos añadiendo una clase parcial a nuestro proyecto. Por ejemplo, podemos añadir un método llamado "GetCustomer()" que nos permita buscar y obtener objetos Customer de la base de datos a partir del valor CustomerID: 
VB:
C#: 
Paso 2: Usando nuestra capa de datos (seguimos sin SPROCs) 
Ya tenemos una capa de datos que encapsula nuestro modelo de datos, integra reglas de validación, y nos permite consultar, actualizar, insertar y borrar datos. 
Veamos ahora un escenario simple usándolo para obtener un objeto customer existente, actualizamos el ContactName y el PhoneNumber, y creamos un nuevo objeto Order para asociarlos. El siguiente código hace todo eso en una sola transacción. LINQ to SQL se asegura de que las reglas de validación se cumplen ántes de guardar nada en la base de datos: 
VB:
C#: 
LINQ to SQL monitoriza todas las modificaciones de los objetos que hemos obtenido de la base de datos, y guarda los objetos que añadimos. Cuando llamamos al método DataContext.SubmitChanges(), LINQ to SQL comprueba las reglas que hemos establecido, y genera automáticamente la SQL que actualizará el registro de Customer e insertará un nuevo registro en la tabla Orders 
Un momento - Pensaba que este post iba sobre SPROCs 
Si aún estais leyendo, os preguntaréis dónde están los SPROCs en este post. ¿Porque os estoy mostrando el código de arriba que hace que se genere una SQL dinámica? ¿Por qué no os he enseñado cómo llamar a un SPROC para hacer las inserciones/actualizaciones/borrados todavía? 
La razón es que el modelo de programación de LINQ to SQL tanto para trabajar con objetos modelados mediante SPROC es exactamente el mismo que con SQL dinámico. La manera en que añadimos validación lógica es exactamente igual (así que todas las reglas que hemos añadido a nuestro modelo de datos se aplicarán también si usamos SPROCs). El código anterior que hemos usado para obtener un cliente, actualizarlo y añadir un nuevo pedido es exactamente igual tanto si usamos SQL dinámico como si usamos SPROCs.
Esta simetría en el modelo de programación es muy potente ya que no tenemos que aprender dos maneras diferentes de hacer las cosas, ni tenemos que decidir al principio del proyecto qué técnica usar, si SPROC o no. Podemos empezar usando el SQL dinámico que nos da LINQ to SQL para las consultas, inserciones, actualizaciones y borrados. Podemos añadir reglas de validación a nuestro modelo. Y luego podemos actualizar el modelo de datos para usar SPROCs - o no. El código y los test que escribamos contra las clases del modelo de datos serán exáctamente iguales. 
De ahora en adelante veremos cómo podemos actualizar nuestro modelo de datos usando SPROCs para actualizar/insertar/borrar - mientras seguimos usando las mismas reglas de validación y trabajaremos con los mismos códigos anteriores. 
Cómo usar SPROCs en inserciones, actualizaciones y borrados 
Podemos modificar la capa de datos que estamos construyendo para que use SPROCs, en lugar de SQL dinámico de dos maneras: 
1. Usando el diseñador de LINQ to SQL para configurar gráficamente la ejecución de los SPROCs en las diferentes operaciones o 
2. Añadir una clase parcial NorthwindDataContext a nuestro proyecto, y entonces implementar los métodos necesarios para la inserción, borrado y actualización. (por ejemplo: InsertOrder, UpdateOrder, DeleteOrder) que serán llamados cuando se realize alguna de las operaciones asociadas. Estos métodos parciales serán pasados a las instancias del modelo de datos que queramos actualizar, y podemos ejecutar tanto SPROC como código SQL para guardarlo. 
Cuando usemos la primera aproximación para configurar gráficamente los SPROCs que llamaremos, por debajo se está generando el mismo código (en clases parciales que crea él solo) que escribiríamos si elegimos la segunda opción. En general os recomiendo que uséis el diseñador de LINQ to SQL para configurar los SPROCs en el 90% de los casos - y crear las llamadas personalizadas a procedimientos almacenados en escenarios más avanzados. 
Paso 3: Hacer otras inserciones con un SPROC 
Empezaremos cambiando nuestro modelo de datos para que use SPROCs con el objeto Order. 
Primero nos vamos a la ventana de "Explorador de Servidores" (Server Explorer) de Visual Studio, expandimos el nodo "Stored Procedures" de nuestra base de datos, hacemos clic con el botón derecho y elegimos la opción "Add New Stored Procedure": 
Creamos el nuevo procedimiento almacenado que llamaremos "InsertOrder" que añade una nueva fila order a la tabla Orders:
Fijáos que hemos definido el parámetro "OrderId" como un parámetro de salida. ESto es debido a que la columna OrderID es una columna identidad que se autoincrementa cada vez que se añade un nuevo registro. Quien llame a este SPROC deverá pasarle un valor null en ese parámetro - y el SPROC devolverá en ese parámetro el nuevo valor OrderID (llamando a la función SCOPE_IDENTITY() al final del SPROC). 
Después de crear el SPROC abrimos el diseñador de LINQ to SQL. De la misma forma que vimos en la sexta parte de esta serie, podemos arrastrar y soltar SPROCs desde la ventana "server explorer" al diseñador. Esto es lo que haremos con el nuevo SPROC que acabamos de crear:
El último paso será decirle a nuestra capa de datos que use el SPROC InsertOrder cuano inserter un nuevo objeto Order en la base de datos. Esto lo hacemos seleccionando la clase "Order" del diseñador LINQ to SQL, y en las propiedades clicamos el botón "..." del método Insert: 
Hacemos clic en el botón "..." y aparecerá una ventana que nos permite personalizar las operaciones de inserción:
Fijaos cómo el modo po defecto ("Use Runtime") está configurado para usar LINQ to SQL como generador dinámico de las SQL. Para cambiarlo seleccionamos el radio buton "Customize" y seleccionamos el SPROC InsertOrder de la lista de SPROCS disponibles: 
El diseñador de LINQ to SQL calculará una lista de parametros para el SPROC que hemos seleccionado, permitiéndonos mapear las propiedades de nuestra clase Order a los parámetros del SPROC InsertOrder. Por defecto seleccionará el que más se parezca en el nombre. Podemos cambiarlo si queremos.
Una vez que cliquemos en OK está listo. Ahora cada vez que añadamos un nuevo pedido a nuestro DataContext e invoquemos al método SubmitChanges(), se ejecutará el SPROC InsertOrder. 
Importante: Aunque estemos usando SPROC para la persistencia, el método parcial "OnValidate()" que creamos (en la primer parte de esta serie) para encapsular las reglas de validación para los pedidos seguirán ejecutándose antes de realizar cualquier cambio. Es decir, tenemos una forma limpia de encapsular la lógica de negocio y las reglas de validación en nuestros modelos de datos, y podemos reutilizarlos tanto si usamos SQL o SPROCS. 
Paso 4: Actualizando los clientes con SPROCs. 
Ahora vamos a modificar el objeto Customer para manejar las actualizaciones con un SPROC. 
Empezamos creando el SPROC "UpdateCustomer": 
Fijaos que además de pasar el parámetro @CustomerID, también tenemos un parámetro @Original_CustomerID. La columna CustomerID de la tabla Customers no es un campo autoincremental, y puede modificarse cuando hagamos una actualización. Por tanto necesitamos ser capaces de decirle al SPROC cual es el CustomerID original y el nuevo CustomerID. Vamos a ver cómo mapeamos esto con el diseñador de LINQ to SQL. 
Veréis que estamos pasando un parámetro llamado @Version (que es una marca de tiempo) al SPROC. Es una nueva columna que he añadido a la tabla Customers para ayudarme a controlar la concurrencia optimista. Veremos en más detalle este tema en otro post de esta serie - pero en resumen es que LINQ to SQL soporta completamente la concurrencia optimista, y nos permite usar tanto una marca de tiempo o usar valores original/nuevo para detectar si ha habido algún cambio por parte de otro usuario ántes de guardar los datos. Para este ejemplo usaremos una marca de tiempo ya que hace que el código sea mucho más claro. 
Una vez que tenemos nuestro SPROC, lo arrastramos y soltamos al diseñador LINQ to SQL para añadirlo como método a nuestro DataContext. Seleccionamos la clase Customer y hacemos clic en el botón "..." de la propiedad Update:
Seleccionamos el radio button "Customize" y seleccionamos el SPROC UpdateCustomer: 
Cuando mapeamos las propiedades de los objetos Customer con los parámetros del SPROC, veremos que tenemos que decidir si poner la propiedad "current" en el objeto de datos, o si poner el valor original que estaba en la base de datos antes de obtener el objeto. Por ejemplo, tendremos que asegurarnos de que mapeamos el valor "current" de la propiedad CustomerID en el parámetro @CustomerID, y el valor original en el parámetro @original_customerID.
Cuando hacemos clic en OK ya esta terminado. Ahora cuando actualizemos cualquier cliente y llamemos a SubmitChanges() se ejectuará el SPROC UpdateCustomer en lugar de ejecutarse un SQL dinámico. 
Importante: Aunque ahora estemos usando SPROC, el método parcial "OnPhoneChanging()" de la clase Customer (que creamos en el primer post de esta serie) para validar los números de teléfono se seguirá ejecutando de la misma manera ántes de que se guarden los cambios. Tenemos de esta forma una forma limpia de encapsular reglas de negocio y validación a nuestros modelos de datos, y podemos reutilizarlos tanto si usamos SQL dinámico o SPROCs. 
Paso 5: Usando el modelo de datos otra vez (esta vez con SPROCs) 
Ahora que ya tenemos configurada nuestra capa de datos para usar SPOCs en lugar de SQL dinámico, podemos ejecutar el mismo código que vimos en el paso 2: 
Ahora las actualizacion del objeto Customer, y la inserción del objeto ORder, se están ejecutando a través de SPROCs en lugar de SQL dinámico. La lógica de validación que definimos se siguen ejecutando como antes, y el código sigue siendo exactamente el mismo. 
Apuntes avanzados cuando usamos SPROCs 
Veamos unas cuantas recomendaciones útiles para escenarios con SPROC más avanzados con LINQ to SQL 
Uso de parámetros de salida 
En casos de inserción (Paso 3) hemos visto cómo podemos devolver el nuevo valor OrderID (que es un valor identidad y autoincremental de la tabla Orders) usando un parámetro de salida en el SPROC. No estamos limitados a devolver sólo valores de columnas identidad con SPROCs y LINQ to SQL - en realidad podemos actualizar y devolver cualquier parámetro. Podemos usarlo tanto para insetar como para actualizar. LINQ to SQL tomará el valor resultado y actualizará la propiedad asociada en el modelo de dato sin que tengamos que hacer ninguna consulta extra para refrescarlo o calcularlo de nuevo. 
¿Que pasa si el SPROC da un error? 
Si el SPROC da un error mientras inserta, actualiza o borra un dato, LINQ to SQL cancelará y deshará la transacción de todos los cambios asociados a la llamada SubmitChanges(). De manera que nos aseguramos la consistencia de los datos. 
¿Podemos escribir código en lugar de usar el diseñador para llamar a un SPROC? 
Como ya comenté al principio, podemos usar tanto el diseñador de LINQ to SQL para mapear las operaciones con SPROC o podemos añadir métodos parciales a la clase DataContext programáticamente e invocarlos nosotros mismo.
Aquí tenéis un ejemplo del código que deberíamos escribir para sobreescribir el método UpdateCustomer de la clase NorthwindDataContext: 
Este código es el que fué generado con el diseñador de LINQ to SQL cuando lo usamos para mapear el SPROC y asociarlo a la operación de Update del objeto Customer. Podemos usarlo como un punto de partida y añadir alguna lógica adicional para hacerlo más personalizado (por ejemplo: usar el valor de retorno del SPROC para lanzar excepciones personalizadas). 
Resumen 
LINQ to SQL es un ORM muy flexible. Nos permite escribir código limpio orientado a objetos para obtener, acutalizar e insertar datos. 
Lo mejor de todo es que nos permite diseñar una capa de datos realmente limpia e independiente de cómo se guardan y cargan los datos de la base de datos. Podemos usar SQL dinámico o SPROCs para esas operaciones. Lo mejor es que el código que use nuestra capa de datos, y todas las reglas de negocio asociadas, serán las mismas sin importar que método de persistencia estemos usando. 
En futuros post veremos más conceptos sobre LINQ to SQL como: Herencia simple de tablas, Carga retrasada, concurrencia optimista, y administración de escenarios de N-capas. ESta semana estaré de vacaciones y espero tener más tiempo libre para escribir alguno de ellos.

Mais conteúdo relacionado

Mais procurados

CONEXION VISUAL STUDIO.NET - SQL SERVER
CONEXION VISUAL STUDIO.NET - SQL SERVERCONEXION VISUAL STUDIO.NET - SQL SERVER
CONEXION VISUAL STUDIO.NET - SQL SERVER
Darwin Durand
 
CREACION DE DLL Y USO (Ejemplo desarrollado)
CREACION DE DLL Y USO (Ejemplo desarrollado)CREACION DE DLL Y USO (Ejemplo desarrollado)
CREACION DE DLL Y USO (Ejemplo desarrollado)
Darwin Durand
 
ConexióN De Una Base De Datos De Sql Con C#
ConexióN De Una Base De Datos De Sql Con C#ConexióN De Una Base De Datos De Sql Con C#
ConexióN De Una Base De Datos De Sql Con C#
LUZ ARIZPE
 
Cliente servidor
Cliente servidorCliente servidor
Cliente servidor
CincoC
 

Mais procurados (19)

la mejor forma de Conectar c# con mysql con archivos de configuracion
 la mejor forma de Conectar c# con mysql con archivos de configuracion  la mejor forma de Conectar c# con mysql con archivos de configuracion
la mejor forma de Conectar c# con mysql con archivos de configuracion
 
Introduccion a-linq..www.freelibros.com
Introduccion a-linq..www.freelibros.comIntroduccion a-linq..www.freelibros.com
Introduccion a-linq..www.freelibros.com
 
CONEXION VISUAL STUDIO.NET - SQL SERVER
CONEXION VISUAL STUDIO.NET - SQL SERVERCONEXION VISUAL STUDIO.NET - SQL SERVER
CONEXION VISUAL STUDIO.NET - SQL SERVER
 
Conexión a SQL Server con C#.NET a través de ODBC
Conexión a SQL Server con C#.NET a través de ODBCConexión a SQL Server con C#.NET a través de ODBC
Conexión a SQL Server con C#.NET a través de ODBC
 
Aprenda a conectar sql y c# en 19 sencillos pasos!
Aprenda a conectar sql y c# en 19 sencillos pasos!Aprenda a conectar sql y c# en 19 sencillos pasos!
Aprenda a conectar sql y c# en 19 sencillos pasos!
 
Conexión de visual basic a bases de datos. María Parra
Conexión de visual basic a bases de datos. María ParraConexión de visual basic a bases de datos. María Parra
Conexión de visual basic a bases de datos. María Parra
 
Conexión a sql server con c#
Conexión a sql server con c#Conexión a sql server con c#
Conexión a sql server con c#
 
manual visual basic 02
manual visual basic 02 manual visual basic 02
manual visual basic 02
 
CREACION DE DLL Y USO (Ejemplo desarrollado)
CREACION DE DLL Y USO (Ejemplo desarrollado)CREACION DE DLL Y USO (Ejemplo desarrollado)
CREACION DE DLL Y USO (Ejemplo desarrollado)
 
Bases de datos_angelina_monetti
Bases de datos_angelina_monettiBases de datos_angelina_monetti
Bases de datos_angelina_monetti
 
Conexión c# sql server
Conexión c# sql serverConexión c# sql server
Conexión c# sql server
 
Instituto tecnologico superior
Instituto tecnologico superiorInstituto tecnologico superior
Instituto tecnologico superior
 
Como conectar visual basic 6.0 a una base de datos microsoft sql server
Como conectar visual basic 6.0 a una base de datos microsoft sql serverComo conectar visual basic 6.0 a una base de datos microsoft sql server
Como conectar visual basic 6.0 a una base de datos microsoft sql server
 
ConexióN De Una Base De Datos De Sql Con C#
ConexióN De Una Base De Datos De Sql Con C#ConexióN De Una Base De Datos De Sql Con C#
ConexióN De Una Base De Datos De Sql Con C#
 
Curso SQL-C# Basico
Curso SQL-C# BasicoCurso SQL-C# Basico
Curso SQL-C# Basico
 
Base datosvisualc#express2008
Base datosvisualc#express2008Base datosvisualc#express2008
Base datosvisualc#express2008
 
Dce2 ejercicios asp.net
Dce2 ejercicios asp.netDce2 ejercicios asp.net
Dce2 ejercicios asp.net
 
Cliente servidor
Cliente servidorCliente servidor
Cliente servidor
 
Ejercicio basico en asp.net LOZADA ERICK
Ejercicio basico en asp.net LOZADA ERICKEjercicio basico en asp.net LOZADA ERICK
Ejercicio basico en asp.net LOZADA ERICK
 

Semelhante a Linq to sql 7

Taller1 generación codigopersistencia
Taller1 generación codigopersistenciaTaller1 generación codigopersistencia
Taller1 generación codigopersistencia
Victor Aravena
 
Guia 1 conexion a base de datos sql server
Guia 1 conexion a base de datos sql serverGuia 1 conexion a base de datos sql server
Guia 1 conexion a base de datos sql server
Mayito CH
 

Semelhante a Linq to sql 7 (20)

Linq to sql 5
Linq to sql 5Linq to sql 5
Linq to sql 5
 
Linq to sql 2
Linq to sql 2Linq to sql 2
Linq to sql 2
 
Mvc
MvcMvc
Mvc
 
Ejemplo Linq To SQL
Ejemplo Linq To SQLEjemplo Linq To SQL
Ejemplo Linq To SQL
 
Tópicos Avanzados de Programación - Unidad 4 Acceso a datos
Tópicos Avanzados de Programación - Unidad 4 Acceso a datosTópicos Avanzados de Programación - Unidad 4 Acceso a datos
Tópicos Avanzados de Programación - Unidad 4 Acceso a datos
 
My Sql A C#
My Sql A C#My Sql A C#
My Sql A C#
 
DAM-S7.pptx
DAM-S7.pptxDAM-S7.pptx
DAM-S7.pptx
 
ejemplo de diseño
ejemplo de diseñoejemplo de diseño
ejemplo de diseño
 
Guia herramientas de bd
Guia herramientas de bdGuia herramientas de bd
Guia herramientas de bd
 
Base de datos
Base de datosBase de datos
Base de datos
 
Guía herramientas de BD PHP
Guía herramientas de BD PHPGuía herramientas de BD PHP
Guía herramientas de BD PHP
 
Unidad 4
Unidad 4Unidad 4
Unidad 4
 
Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...
Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...
Programación de Base de Datos - Unidad II: Aplicaciones con Arquitectura Clie...
 
Corp. In. Tec. S.A. - Capacitaciones en Informática - Programación con CodeIg...
Corp. In. Tec. S.A. - Capacitaciones en Informática - Programación con CodeIg...Corp. In. Tec. S.A. - Capacitaciones en Informática - Programación con CodeIg...
Corp. In. Tec. S.A. - Capacitaciones en Informática - Programación con CodeIg...
 
Jquery Hmvc
Jquery HmvcJquery Hmvc
Jquery Hmvc
 
Evolution INTech - Acceso a bases de datos con Minimal APIs de .NET 6.pptx
Evolution INTech - Acceso a bases de datos con Minimal APIs de .NET 6.pptxEvolution INTech - Acceso a bases de datos con Minimal APIs de .NET 6.pptx
Evolution INTech - Acceso a bases de datos con Minimal APIs de .NET 6.pptx
 
Conexión de Base de Datos
Conexión de Base de DatosConexión de Base de Datos
Conexión de Base de Datos
 
Taller1 generación codigopersistencia
Taller1 generación codigopersistenciaTaller1 generación codigopersistencia
Taller1 generación codigopersistencia
 
CONEXION A BASE DE DATOS - VISUAL BASIC 6.0
CONEXION A BASE DE DATOS - VISUAL BASIC 6.0 CONEXION A BASE DE DATOS - VISUAL BASIC 6.0
CONEXION A BASE DE DATOS - VISUAL BASIC 6.0
 
Guia 1 conexion a base de datos sql server
Guia 1 conexion a base de datos sql serverGuia 1 conexion a base de datos sql server
Guia 1 conexion a base de datos sql server
 

Mais de jcfarit (20)

Conceptos basicos de telefonia
Conceptos basicos de telefoniaConceptos basicos de telefonia
Conceptos basicos de telefonia
 
Manual de usuario Ruani
Manual de usuario RuaniManual de usuario Ruani
Manual de usuario Ruani
 
Unidad 3 gestion de procesos en linux
Unidad 3 gestion de procesos en linuxUnidad 3 gestion de procesos en linux
Unidad 3 gestion de procesos en linux
 
Arquitectura General del Sistema Operativo Linux
Arquitectura General del Sistema Operativo LinuxArquitectura General del Sistema Operativo Linux
Arquitectura General del Sistema Operativo Linux
 
ISO 27001 -6
ISO 27001 -6ISO 27001 -6
ISO 27001 -6
 
ISO 27001 - 5
ISO 27001 - 5ISO 27001 - 5
ISO 27001 - 5
 
ISO 27001 4
ISO 27001 4ISO 27001 4
ISO 27001 4
 
ISO 27001 -3
ISO 27001 -3 ISO 27001 -3
ISO 27001 -3
 
ISO 27001
ISO 27001ISO 27001
ISO 27001
 
ISO 27001
ISO 27001ISO 27001
ISO 27001
 
Curso ubuntuimprimible
Curso ubuntuimprimibleCurso ubuntuimprimible
Curso ubuntuimprimible
 
Curso ubuntu1extraimprimible
Curso ubuntu1extraimprimibleCurso ubuntu1extraimprimible
Curso ubuntu1extraimprimible
 
Autentificación-Firma Digital
Autentificación-Firma DigitalAutentificación-Firma Digital
Autentificación-Firma Digital
 
Auditoría de Routers y Switches
Auditoría de Routers y SwitchesAuditoría de Routers y Switches
Auditoría de Routers y Switches
 
Arquitectura multi agente.doc
Arquitectura multi agente.docArquitectura multi agente.doc
Arquitectura multi agente.doc
 
Aplicaciones Criptográficas en Entornos Económicos
Aplicaciones Criptográficas en Entornos EconómicosAplicaciones Criptográficas en Entornos Económicos
Aplicaciones Criptográficas en Entornos Económicos
 
Análisis de los sistemas de dinero electrónico
Análisis de los sistemas de dinero electrónicoAnálisis de los sistemas de dinero electrónico
Análisis de los sistemas de dinero electrónico
 
Suneval
SunevalSuneval
Suneval
 
Guia plan de_clases
Guia plan de_clasesGuia plan de_clases
Guia plan de_clases
 
Los medios de enseñanza aprendizaje
Los medios de enseñanza aprendizajeLos medios de enseñanza aprendizaje
Los medios de enseñanza aprendizaje
 

Último

Unidad V. Disoluciones quimica de las disoluciones
Unidad V. Disoluciones quimica de las disolucionesUnidad V. Disoluciones quimica de las disoluciones
Unidad V. Disoluciones quimica de las disoluciones
chorantina325
 

Último (6)

Emprende en SPA Segundo día CENEC Mexico
Emprende en SPA Segundo día CENEC MexicoEmprende en SPA Segundo día CENEC Mexico
Emprende en SPA Segundo día CENEC Mexico
 
Unidad V. Disoluciones quimica de las disoluciones
Unidad V. Disoluciones quimica de las disolucionesUnidad V. Disoluciones quimica de las disoluciones
Unidad V. Disoluciones quimica de las disoluciones
 
PPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjj
PPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjjPPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjj
PPT-HISTORIA-6°-ABC.pptxjjjjjjjjjjjjjjjjjjjjjj
 
¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...
¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...
¡Descubre el Poder del Masaje Holístico en nuestra Primera Sesión del Seminar...
 
Corte de luz 2024 Guayaquil Guayas ecuad
Corte de luz 2024 Guayaquil Guayas ecuadCorte de luz 2024 Guayaquil Guayas ecuad
Corte de luz 2024 Guayaquil Guayas ecuad
 
Las redes sociales en el mercado digital
Las redes sociales en el mercado digitalLas redes sociales en el mercado digital
Las redes sociales en el mercado digital
 

Linq to sql 7

  • 1. LINQ to SLQ (Parte 7 – Actualizando la base de datos con procedimientos almacenados) 9 respuestas En las últimas semanas he escrito una serie de post sobre LINQ to SQL. Es un ORM integrado en .NET 3.5, y nos permite modelar bases de datos relacionales con clases de .NET. Podemos usar expresiones LINQ para consultar a la base de datos, actualiazarla, insertar y borrar datos. Aquí tenéis los enlaces a los otros post:  Parte 1: Introducción a LINQ to SQL  Parte 2: Definiendo el modelo de datos.  Parte 3: Consultando la base de datos  Parte 4: Actualizando la base de datos.  Parte 5: Enlazar controles de interfaz de usuario con el ASP:LinqDatSource  Parte 6: Obtener datos con procedimientos almacenados. En la sexta parte vimos cómo podemos usar procedimientos almacenados (SPROCs) y funciones definidas por el usuario (UDFs) para consultar la base de datos con el modelo de datos de LINQ to SQL. En el post de hoy veremos cómo podemos usar los SPROCs para actualizar/insertar/borrar datos de nuestra base de datos. Para ayudar a entender esto empezaremos costruyendo una capa de datos para la base de datos de ejemplo Northwind: Paso 1: Crear nuestra capa de acceso a datos (sin SPROCs) En la segunda parte de esta serie vimos cómo usar el diseñador de LINQ to SQL de VS 2008 para crear el siguiente modelo de clases:
  • 2. Añadiendo reglas de validación a nuestro modelo de clases. Después de definir nuestro modelo querremos añadir reglas de validación a nuestro modelo de datos. Podemos hacer esto añadiendo clases parciales a nuestro proyecto y añadir las reglas de validación en esas clases (vimos cómo hacer esto en la cuarta parte de esta serie). Por ejemplo, podemos añadir la lógica necesaria para asegurarnos de que el número de teléfono de los clientes siguen un patrón válido, y otra para asegurarnos de que la fecha de entrega (RequierdDate) es posterior a la fecha actual del pedido (OrderDate). Una vez que hemos definido las clases parciales, estos métodos de validación se ejecutarán cada vez que escribamos código para actualizar nuestros objetos de datos de nuestra aplicación: VB:
  • 3. C#:
  • 4. Añadir un método de ayuda GetCustomer() a nuestro DataContext Una vez que hemos creado nuestro modelo de clases, y que le hemos añadido reglas de validación, podemos consultar e interactuar con los datos. Podemos hacer esto escribiendo expresiones LINQ sobre nuestro modelo de clases (vimos cómo hacer esto en la tercera parte de esta serie). También podemos mapear SPROCs en nuestro DataContext (esto lo vimos en la sexta parte de la serie). Cuando creamos una capa de datos con LINQ to SQL normalmente querremos encapsular consultas comunes de LINQ (o SPROCs) en métodos auxiliares que añadiremos a la clase DataContext. Esto lo conseguimos añadiendo una clase parcial a nuestro proyecto. Por ejemplo, podemos añadir un método llamado "GetCustomer()" que nos permita buscar y obtener objetos Customer de la base de datos a partir del valor CustomerID: VB:
  • 5. C#: Paso 2: Usando nuestra capa de datos (seguimos sin SPROCs) Ya tenemos una capa de datos que encapsula nuestro modelo de datos, integra reglas de validación, y nos permite consultar, actualizar, insertar y borrar datos. Veamos ahora un escenario simple usándolo para obtener un objeto customer existente, actualizamos el ContactName y el PhoneNumber, y creamos un nuevo objeto Order para asociarlos. El siguiente código hace todo eso en una sola transacción. LINQ to SQL se asegura de que las reglas de validación se cumplen ántes de guardar nada en la base de datos: VB:
  • 6. C#: LINQ to SQL monitoriza todas las modificaciones de los objetos que hemos obtenido de la base de datos, y guarda los objetos que añadimos. Cuando llamamos al método DataContext.SubmitChanges(), LINQ to SQL comprueba las reglas que hemos establecido, y genera automáticamente la SQL que actualizará el registro de Customer e insertará un nuevo registro en la tabla Orders Un momento - Pensaba que este post iba sobre SPROCs Si aún estais leyendo, os preguntaréis dónde están los SPROCs en este post. ¿Porque os estoy mostrando el código de arriba que hace que se genere una SQL dinámica? ¿Por qué no os he enseñado cómo llamar a un SPROC para hacer las inserciones/actualizaciones/borrados todavía? La razón es que el modelo de programación de LINQ to SQL tanto para trabajar con objetos modelados mediante SPROC es exactamente el mismo que con SQL dinámico. La manera en que añadimos validación lógica es exactamente igual (así que todas las reglas que hemos añadido a nuestro modelo de datos se aplicarán también si usamos SPROCs). El código anterior que hemos usado para obtener un cliente, actualizarlo y añadir un nuevo pedido es exactamente igual tanto si usamos SQL dinámico como si usamos SPROCs.
  • 7. Esta simetría en el modelo de programación es muy potente ya que no tenemos que aprender dos maneras diferentes de hacer las cosas, ni tenemos que decidir al principio del proyecto qué técnica usar, si SPROC o no. Podemos empezar usando el SQL dinámico que nos da LINQ to SQL para las consultas, inserciones, actualizaciones y borrados. Podemos añadir reglas de validación a nuestro modelo. Y luego podemos actualizar el modelo de datos para usar SPROCs - o no. El código y los test que escribamos contra las clases del modelo de datos serán exáctamente iguales. De ahora en adelante veremos cómo podemos actualizar nuestro modelo de datos usando SPROCs para actualizar/insertar/borrar - mientras seguimos usando las mismas reglas de validación y trabajaremos con los mismos códigos anteriores. Cómo usar SPROCs en inserciones, actualizaciones y borrados Podemos modificar la capa de datos que estamos construyendo para que use SPROCs, en lugar de SQL dinámico de dos maneras: 1. Usando el diseñador de LINQ to SQL para configurar gráficamente la ejecución de los SPROCs en las diferentes operaciones o 2. Añadir una clase parcial NorthwindDataContext a nuestro proyecto, y entonces implementar los métodos necesarios para la inserción, borrado y actualización. (por ejemplo: InsertOrder, UpdateOrder, DeleteOrder) que serán llamados cuando se realize alguna de las operaciones asociadas. Estos métodos parciales serán pasados a las instancias del modelo de datos que queramos actualizar, y podemos ejecutar tanto SPROC como código SQL para guardarlo. Cuando usemos la primera aproximación para configurar gráficamente los SPROCs que llamaremos, por debajo se está generando el mismo código (en clases parciales que crea él solo) que escribiríamos si elegimos la segunda opción. En general os recomiendo que uséis el diseñador de LINQ to SQL para configurar los SPROCs en el 90% de los casos - y crear las llamadas personalizadas a procedimientos almacenados en escenarios más avanzados. Paso 3: Hacer otras inserciones con un SPROC Empezaremos cambiando nuestro modelo de datos para que use SPROCs con el objeto Order. Primero nos vamos a la ventana de "Explorador de Servidores" (Server Explorer) de Visual Studio, expandimos el nodo "Stored Procedures" de nuestra base de datos, hacemos clic con el botón derecho y elegimos la opción "Add New Stored Procedure": Creamos el nuevo procedimiento almacenado que llamaremos "InsertOrder" que añade una nueva fila order a la tabla Orders:
  • 8. Fijáos que hemos definido el parámetro "OrderId" como un parámetro de salida. ESto es debido a que la columna OrderID es una columna identidad que se autoincrementa cada vez que se añade un nuevo registro. Quien llame a este SPROC deverá pasarle un valor null en ese parámetro - y el SPROC devolverá en ese parámetro el nuevo valor OrderID (llamando a la función SCOPE_IDENTITY() al final del SPROC). Después de crear el SPROC abrimos el diseñador de LINQ to SQL. De la misma forma que vimos en la sexta parte de esta serie, podemos arrastrar y soltar SPROCs desde la ventana "server explorer" al diseñador. Esto es lo que haremos con el nuevo SPROC que acabamos de crear:
  • 9. El último paso será decirle a nuestra capa de datos que use el SPROC InsertOrder cuano inserter un nuevo objeto Order en la base de datos. Esto lo hacemos seleccionando la clase "Order" del diseñador LINQ to SQL, y en las propiedades clicamos el botón "..." del método Insert: Hacemos clic en el botón "..." y aparecerá una ventana que nos permite personalizar las operaciones de inserción:
  • 10. Fijaos cómo el modo po defecto ("Use Runtime") está configurado para usar LINQ to SQL como generador dinámico de las SQL. Para cambiarlo seleccionamos el radio buton "Customize" y seleccionamos el SPROC InsertOrder de la lista de SPROCS disponibles: El diseñador de LINQ to SQL calculará una lista de parametros para el SPROC que hemos seleccionado, permitiéndonos mapear las propiedades de nuestra clase Order a los parámetros del SPROC InsertOrder. Por defecto seleccionará el que más se parezca en el nombre. Podemos cambiarlo si queremos.
  • 11. Una vez que cliquemos en OK está listo. Ahora cada vez que añadamos un nuevo pedido a nuestro DataContext e invoquemos al método SubmitChanges(), se ejecutará el SPROC InsertOrder. Importante: Aunque estemos usando SPROC para la persistencia, el método parcial "OnValidate()" que creamos (en la primer parte de esta serie) para encapsular las reglas de validación para los pedidos seguirán ejecutándose antes de realizar cualquier cambio. Es decir, tenemos una forma limpia de encapsular la lógica de negocio y las reglas de validación en nuestros modelos de datos, y podemos reutilizarlos tanto si usamos SQL o SPROCS. Paso 4: Actualizando los clientes con SPROCs. Ahora vamos a modificar el objeto Customer para manejar las actualizaciones con un SPROC. Empezamos creando el SPROC "UpdateCustomer": Fijaos que además de pasar el parámetro @CustomerID, también tenemos un parámetro @Original_CustomerID. La columna CustomerID de la tabla Customers no es un campo autoincremental, y puede modificarse cuando hagamos una actualización. Por tanto necesitamos ser capaces de decirle al SPROC cual es el CustomerID original y el nuevo CustomerID. Vamos a ver cómo mapeamos esto con el diseñador de LINQ to SQL. Veréis que estamos pasando un parámetro llamado @Version (que es una marca de tiempo) al SPROC. Es una nueva columna que he añadido a la tabla Customers para ayudarme a controlar la concurrencia optimista. Veremos en más detalle este tema en otro post de esta serie - pero en resumen es que LINQ to SQL soporta completamente la concurrencia optimista, y nos permite usar tanto una marca de tiempo o usar valores original/nuevo para detectar si ha habido algún cambio por parte de otro usuario ántes de guardar los datos. Para este ejemplo usaremos una marca de tiempo ya que hace que el código sea mucho más claro. Una vez que tenemos nuestro SPROC, lo arrastramos y soltamos al diseñador LINQ to SQL para añadirlo como método a nuestro DataContext. Seleccionamos la clase Customer y hacemos clic en el botón "..." de la propiedad Update:
  • 12. Seleccionamos el radio button "Customize" y seleccionamos el SPROC UpdateCustomer: Cuando mapeamos las propiedades de los objetos Customer con los parámetros del SPROC, veremos que tenemos que decidir si poner la propiedad "current" en el objeto de datos, o si poner el valor original que estaba en la base de datos antes de obtener el objeto. Por ejemplo, tendremos que asegurarnos de que mapeamos el valor "current" de la propiedad CustomerID en el parámetro @CustomerID, y el valor original en el parámetro @original_customerID.
  • 13. Cuando hacemos clic en OK ya esta terminado. Ahora cuando actualizemos cualquier cliente y llamemos a SubmitChanges() se ejectuará el SPROC UpdateCustomer en lugar de ejecutarse un SQL dinámico. Importante: Aunque ahora estemos usando SPROC, el método parcial "OnPhoneChanging()" de la clase Customer (que creamos en el primer post de esta serie) para validar los números de teléfono se seguirá ejecutando de la misma manera ántes de que se guarden los cambios. Tenemos de esta forma una forma limpia de encapsular reglas de negocio y validación a nuestros modelos de datos, y podemos reutilizarlos tanto si usamos SQL dinámico o SPROCs. Paso 5: Usando el modelo de datos otra vez (esta vez con SPROCs) Ahora que ya tenemos configurada nuestra capa de datos para usar SPOCs en lugar de SQL dinámico, podemos ejecutar el mismo código que vimos en el paso 2: Ahora las actualizacion del objeto Customer, y la inserción del objeto ORder, se están ejecutando a través de SPROCs en lugar de SQL dinámico. La lógica de validación que definimos se siguen ejecutando como antes, y el código sigue siendo exactamente el mismo. Apuntes avanzados cuando usamos SPROCs Veamos unas cuantas recomendaciones útiles para escenarios con SPROC más avanzados con LINQ to SQL Uso de parámetros de salida En casos de inserción (Paso 3) hemos visto cómo podemos devolver el nuevo valor OrderID (que es un valor identidad y autoincremental de la tabla Orders) usando un parámetro de salida en el SPROC. No estamos limitados a devolver sólo valores de columnas identidad con SPROCs y LINQ to SQL - en realidad podemos actualizar y devolver cualquier parámetro. Podemos usarlo tanto para insetar como para actualizar. LINQ to SQL tomará el valor resultado y actualizará la propiedad asociada en el modelo de dato sin que tengamos que hacer ninguna consulta extra para refrescarlo o calcularlo de nuevo. ¿Que pasa si el SPROC da un error? Si el SPROC da un error mientras inserta, actualiza o borra un dato, LINQ to SQL cancelará y deshará la transacción de todos los cambios asociados a la llamada SubmitChanges(). De manera que nos aseguramos la consistencia de los datos. ¿Podemos escribir código en lugar de usar el diseñador para llamar a un SPROC? Como ya comenté al principio, podemos usar tanto el diseñador de LINQ to SQL para mapear las operaciones con SPROC o podemos añadir métodos parciales a la clase DataContext programáticamente e invocarlos nosotros mismo.
  • 14. Aquí tenéis un ejemplo del código que deberíamos escribir para sobreescribir el método UpdateCustomer de la clase NorthwindDataContext: Este código es el que fué generado con el diseñador de LINQ to SQL cuando lo usamos para mapear el SPROC y asociarlo a la operación de Update del objeto Customer. Podemos usarlo como un punto de partida y añadir alguna lógica adicional para hacerlo más personalizado (por ejemplo: usar el valor de retorno del SPROC para lanzar excepciones personalizadas). Resumen LINQ to SQL es un ORM muy flexible. Nos permite escribir código limpio orientado a objetos para obtener, acutalizar e insertar datos. Lo mejor de todo es que nos permite diseñar una capa de datos realmente limpia e independiente de cómo se guardan y cargan los datos de la base de datos. Podemos usar SQL dinámico o SPROCs para esas operaciones. Lo mejor es que el código que use nuestra capa de datos, y todas las reglas de negocio asociadas, serán las mismas sin importar que método de persistencia estemos usando. En futuros post veremos más conceptos sobre LINQ to SQL como: Herencia simple de tablas, Carga retrasada, concurrencia optimista, y administración de escenarios de N-capas. ESta semana estaré de vacaciones y espero tener más tiempo libre para escribir alguno de ellos.