PROGRAMACION ORIENTADA A OBJETOS
April 20, 2017 | Author: Manuel López | Category: N/A
Short Description
Download PROGRAMACION ORIENTADA A OBJETOS...
Description
Programación Orientada a Objetos II
2
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
3
ÍNDICE Presentación
5
Red de contenidos
6
Sesiones de aprendizaje Unidad de aprendizaje 1 SEMANA 1 SEMANA 2 SEMANA 3
: Arquitectura de ADO .NET, conexión a un base de datos, consulta de datos : Operaciones de consultas y recuperación de datos utilizando DataAdapter, DataReader y Command : Manejo del TableAdapter, Usando LINQ to SQL.
7 23 39
: Modificación de datos de una fuente de datos, manejo de transacciones de datos Unidad de aprendizaje 2
59
SEMANA 5
: Operaciones desconectadas con programación
83
SEMANA 6 SEMANA 7
: Operaciones desconectadas: Manejo del DataView y el DataTableReader desde un DataSet : Semana de exámenes parciales teoría
SEMANA 8
: Semana de exámenes parciales laboratorio
SEMANA 4
103
Unidad de aprendizaje 3 SEMANA 9
: Manejo de Crystal Report
115
Unidad de aprendizaje 4 SEMANA 10 : Modelo relacional de objetos: LINQ to SQL
131
SEMANA 11 : Modelo ADO.NET Entity FrameWork, arquitectura
147
SEMANA 12 : Actualización de datos utilizando objetos EntityClient
163
Unidad de aprendizaje 5 SEMANA 13 : Operaciones XML en datos desconectados Procesamiento de datos XML utilizando DOM SEMANA 14 : Consulta XML utilizando XPath,
177 201
SEMANA 15 : Examen final de laboratorio SEMANA 16 : Sustentación de proyectos SEMANA 17 : Examen final de teoría
CIBERTEC
CARRERAS PROFESIONALES
4
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
5
PRESENTACIÓN
Visual Studio 2008 y su plataforma .NET FrameWork 3.5 es un amplio conjunto de bibliotecas de clases donde se incluye ADO .NET 3.5 que representa las clases en el Acceso de Datos, el cual sufre de avances importantes en el aumento de la productividad. Programación Orientada a Objetos II pertenece a la línea de tecnología y se dicta en las carreras de tecnología de la institución. El curso brinda un conjunto de herramientas de programación para trabajar con un origen de datos que permita al alumno realizar operaciones de consulta y actualización de datos en forma eficiente. El manual para este curso ha sido diseñado bajo la modalidad de unidades de aprendizaje, las que desarrollamos durante semanas determinadas. En cada una de ellas, hallará los logros que se deberá alcanzar al final de la unidad; el tema tratado, el cual será ampliamente desarrollado; y los contenidos, que debe desarrollar. Por último, encontrará las actividades y trabajos prácticos que deberá desarrollar en cada sesión, que le permitirán reforzar lo aprendido en la clase. El curso es eminentemente práctico: consiste en programación visual Basic con base de datos utilizando ADO .NET. La primera parte de este manual nos enseña a familiarizarnos con los objetos de ADO .NET para realizar las consultas y actualizaciones a la base de datos, sea ésta en forma conectada o desconectada a la fuente de datos, mediante ejemplos didácticos. Aprenderemos a utilizar los controles enlazados a los datos que permitan realizar dichos procesos. Luego, vamos a realizar reportes y gráficos utilizando el motor del Crystal Report, a continuación realizamos operaciones de consulta actualización a través del objeto Entity; y por último desarrollamos procesos para manejar XML.
CIBERTEC
CARRERAS PROFESIONALES
6
RED DE CONTENIDOS
Programación Orientada a Objetos II
Operaciones de consulta y actualización utilizando ADO.NET
Arquitectu ra de ADO.NET
Operacion de consulta y actualizar datos
CARRERAS PROFESIONALES
Manejo de DataAdapter, DataReader, Command , Table Adapter y LINQ to SQL
Operaciones desconectadas a un origen de datos
Manejo de DataSet, DataTable
Consultas utilizando TableDataRe ader
Manejo de Reportes
Diseño de Crystal Report
Manejo de parámetros
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
7
UNIDAD DE APRENDIZAJE
1 SEMANA
1 ARQUITECTURA DE ADO .NET, CONEXIÓN A UN ORIGEN DE DATOS Y CONSULTA DE DATOS LOGRO DE LA UNIDAD DE APRENDIZAJE Al término de la unidad, los alumnos elaboran aplicaciones Windows .NET que se conectan a un origen de datos utilizando los objetos de ADO.NET para realizar operaciones de consulta y actualización de datos.
TEMARIO • • • • • •
Arquitectura y componentes de ADO.NET. Administración almacenamiento de una cadena de conexión a un origen datos. Operaciones de consulta sobre un origen de datos. Recuperación de datos utilizando DataAdapter, DataReader y Command Manejo de TableAdapter, Usando LINQ to SQL Modificación de datos, manejo de transacciones de datos y excepciones.
de
ACTIVIDADES PROPUESTAS • • • •
CIBERTEC
Los alumnos se conectan a un origen de datos. Los alumnos consultan los datos en un origen de datos, utilizando sentencias SQL. Los alumnos consultan los datos por diversos criterios en un origen de datos utilizando sentencias SQL. Los alumnos manejan los controles enlazados a los datos para realizar operaciones de consulta.
CARRERAS PROFESIONALES
8
1. INTRODUCCION AL ADO .NET 3.5 En la plataforma .NET, esos servicios reciben la denominación genérica de ADO.NET, ha llegado a su versión 3.5 con Visual Studio 2008. Esta nueva iteración aporta una serie de interfaces y objetos, así como nuevos controles y mejoras en las clases ya existentes, y también en el propio motor que se encarga de la manipulación de los datos en el cliente, incrementando su rendimiento considerablemente. ADO.NET incorpora varios proveedores de datos que permiten conectar con SQL Server y Oracle, así como otros que facilitan el uso de controladores ODBC y OLE DB para acceder a aquellos provenientes de Excel, Access, MySQL, etc. Además incorpora el nuevo modelo de factorías que hace posible un acceso genérico a orígenes de datos, la obtención de información de esquema, las características específicas para SQL Server o las nuevas capacidades del objeto Datatable.
2. ARQUITECTURA DE ADO .NET Tradicionalmente, el procesamiento de datos ha dependido principalmente de un modelo de dos niveles basado en una conexión. A medida que el procesamiento de datos utiliza cada vez más arquitecturas de varios niveles, los programadores están pasando a un enfoque sin conexión con el fin de proporcionar una escalabilidad mejor para sus aplicaciones.
ARQUITECTURA ADO.NET 2.0
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
9
3. PROVEEDOR DE DATOS ADO .NET Cualquier aplicación que utiliza ADO.NET accede a un origen de datos mediante un Provider o proveedor de datos. Un proveedor de datos permite conectarse a una base e datos, ejecutar comandos y obtener resultados. Cada proveedor de datos implementa interfaces para sus objetos.
3.1 Implementaciones de los proveedores de datos Proveedor de Datos de .NET System.Data.SqlClient: Acceso a datos para SQL Server 7.0 o posterior System.Data.OleDb: Origen de datos que se exponen mediante OLE DB System.Data.Odbc: Origen de datos que se exponen mediante ODBC System.Data.OracleClient: Acceso a datos de Oracle 8.1.7 o posterior
3.2 Objetos principales de los proveedores de datos 3.2.1 Connection: Establece una conexión a un origen de datos. 3.2.2 Command: Ejecuta un comando en un origen de datos. Expone Parameters y puede ejecutarse en el ámbito de un objeto Transaction. 3.2.3 DataReader: Lee una secuencia de datos de sólo avance y sólo lectura desde un origen de datos. 3.2.4 DataAdapter: Llena un DataSet y realiza las actualizaciones necesarias en el origen de datos.
CIBERTEC
CARRERAS PROFESIONALES
10
Además de las clases principales citadas en la tabla anterior, los proveedores de datos de .NET Framework también incluyen las que se enumeran en la tabla siguiente.
Objeto
Descripción
Transaction
Permite incluir comandos en las transacciones que se realizan en el origen de datos.
CommandBuilder
Objeto que genera, automáticamente, las propiedades de comando de un DataAdapter o que obtiene, de un procedimiento almacenado, información acerca de parámetros con las que puede rellenar la colección Parameters de un objeto Command.
ConnectionStringBuilder
Objeto que genera y maneja una cadena de conexión utilizada por el objeto Connection.
Parameter
Define los parámetros de entrada, salida y valores devueltos para los comandos y procedimientos almacenados.
Exception
Se devuelve cuando se detecta un error en el origen de datos. En el caso de que el error se detecte en el cliente, los proveedores de datos de .NET Framework inician una excepción de .NET Framework.
Error
Expone la información relacionada con una advertencia o error devueltos por un origen de datos.
ClientPermission
Se proporciona para los atributos de seguridad de acceso a código de los proveedores de datos de .NET Framework.
4. CONEXIÓN A UNA BASE DE DATOS POR ADO .NET El objeto Connection permite conectarse con un determinado origen de datos mediante una cadena de conexión en la que se proporciona la información de autenticación necesaria. El objeto Connection utilizado depende del tipo de origen de datos. Cada proveedor de datos de .NET Framework, incluido en .NET Framework, cuenta con un objeto Connection: • • • •
OleDbConnection, proveedor de datos para OLE DB. SqlConnection, proveedor de datos para SQL Server. OdbcConnection, proveedor de datos para ODBC. OracleConnection, proveedor de datos para Oracle.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
11
4.1 Definición de la cadena de conexión Para conectarse a una base de datos por ADO .NET, debe proveer de una cadena de conexión para identificar la base de datos. Los valores que se incluyen en una cadena de conexión dependen del origen de datos que utilice. A continuación describiremos algunos parámetros de la cadena de conexión.
Parámetro
Descripción
Provider
Parámetro para conexiones de datos OLE DB
Initial Catalog o DataBase
El nombre de la base de datos
Data Source
Nombre o dirección de red del origen de datos
Integrated Security o Trusted_Connection
Si el parámetro es false, debe especificar User ID y Password en la cadena de conexión. Si es true, la cuenta de autenticación es de Windows.
User ID
Cuenta de usuario
Password
Clave de la cuenta de usuario ingresada
Persist Security Info
SI el parámetro es false el origen de datos (data source) no retorna seguridad sensitiva como el password, por defecto es false.
4.2 Conexión a SQL Server mediante ADO .NET El Data Provider del .NET Framework para SQL Server provee la conectividad a SQL Server 7.0 o posterior. Para conectarse a SQL Server utilice la clase SqlConnection desde el namespace System.Data.SqlClient.
4.2.1 Conexión a SQL Server mediante ADO .NET 1. Defina una cadena de conexión que identifique la base de datos a conectar. 2. Cree un objeto SqlConnection, pase la cadena de conexión como argumento al constructor del SqlConnection. 3. Llame al método Open del objeto SqlConnection. 4. Utilice la conexión a la base de datos en su aplicación. 5. Llame al método Close o el método Dispose para cerrar la conexión. Puede usar una sentencia Using, el cual garantiza que el objeto SqlConnection se libera. El siguiente ejemplo muestra como conectarse a la base de datos BDFactura. Dim connectionstring As String = _ "Data Source = (local); Initial Catalog = BDFactura; Integrated Security = true" Dim cn As New SqlConnection(connectionstring) ‘o a través de la Estructura Using Using cn As New SqlConnection(connectionstring) End Using
CIBERTEC
CARRERAS PROFESIONALES
12
Using: Declara el principio de un bloque Using y, opcionalmente, adquiere los recursos del sistema que controla el bloque. A veces su código requiere un recurso no administrado, como un identificador de archivos, un contenedor COM o una conexión SQL. Un bloque Using garantiza la eliminación de uno o más de tales recursos cuando su código termina de usarlos. Esto los pone a disposición de otro código para que los pueda utilizar.
4.3 Conexión con un origen de datos mediante la Librería OleDB El Data Provider del .NET Framework para OLE DB provee la conectividad utilizando la clase OleDbConnection desde el namespace System.Data.OleDbConnection. El proveedor de datos .NET de OLE DB, el formato de la cadena de conexión es igual al que utiliza en ADO con la excepción de la palabra clave Provider. 4.3.1 Conexión a un origen de datos mediante ADO .NET 1. Defina una cadena de conexión que identifique la base de datos a conectar. La cadena de conexión debe incluir un parámetro Provider para especificar cuál es el OLE DB Provider para establecer la conexión. 2. Cree un objeto OleDbConnection, pasar la cadena de conexión como argumento al constructor del OleDbConnection. 3. Llame al método Open del objeto OleDbConnection. 4. Utilice la conexión a la base de datos en tu aplicación 5. Llame el método Close o el método Dispose para cerrar la conexión. Puede usar una sentencia Using, el cual garantiza que el objeto OleDbConnection se libera. Dim connectionstring As String = _ "Provider=SQLOLEDB; server=(local); DataBase=BDFactura; uid=sa;pwd=sql" Dim cn As New SqlConnection(connectionstring)
4.4 Almacenar una cadena de conexión en un app.config Almacene una cadena de conexión en un Application Configuration File, sin tener que editar el código de origen y recompilar la aplicación.
4.4.1 Almacenar una cadena de conexión en un Application Configuration File 1. Abrir un Application Configuration File (app.config). 2. Dentro de la etiqueta añadir una elemento llamado . 3. Dentro de la etiqueta añadir un elemento llamado para cada cadena de conexión. 4. Por cada etiqueta definir un atributo name para especificar el nombre de la cadena de conexión, definir un atributo connectionString para especificar la información de la cadena de conexión. El siguiente ejemplo permite definir una cadena de conexión para la base de datos BDFactura, la cual se llamara cnfactura.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
13
Para utilizar la cadena de conexión almacenada en el app.config, primero defina el namespace Configuration.ConfigurationManager, que utiliza la propiedad ConnectionStrings definida en el app.config, tal como se muestra. Imports System.Data.SqlClient Imports System.Configuration.ConfigurationManager Dim cnstring As String= ConnectionStrings("cnfactura").ConnectionString Using cn As New SqlConnection(cnstring) ...... End Using
5. Ejecutar consultas de base de datos ADO .NET, posee una clase que permite ejecutar consultas sobre la base de datos: sentencias SQL embebidas, procedimientos almacenados, funciones; es la clase SqlCommand. La clase SqlCommand tiene 4 métodos que permite utilizar para ejecutar sentencias SQL:
SqlCommand
Descripción
ExecuteScalar
Ejecuta una consulta que retorna un valor.
ExecuteReader
Ejecuta una consulta que retorna un conjunto de datos a un DataReader.
ExecuteNonQuery
Ejecuta una Sentencia para actualizar los datos.
ExecuteXmlReader
Ejecuta una consulta y retorna un conjunto de datos en XML.
5.1 Ejecutar una consulta en la base de datos 1. Crear un objeto Connection, tal como SqlConnection. 2. Crear un objeto Command, tal como SqlCommand. En el constructor especificar la sentencia sql que se va a ejecutar y especificar la conexión. 3. Al ejecutar la sentencia sql, especificar la propiedad CommandType. Si va a ejecutar una sentencia SQL el valor del CommandType es CommandType.Text; si va a ejecutar un procedimiento almacenado el valor del CommandType será CommandType.StoredProcedure. 4. Llame al método Open del objeto Conexión. 5. Ejecute el método del objeto Command, asignando su resultado a una variable o control. 6. Llame al método Close del objeto conexión. El siguiente ejemplo permite ejecutar una consulta que retorne el número de facturas almacenadas en la base de datos BDFactura Dim cn As New SqlConnection(aConnectionString) Dim cmd as new SqlCommand(“Select Count(*) From fac_cabe” , cn) cmd.CommandType=CommandType.Text cn.Open() Dim count as Integer=CInt(cmd.ExecuteScalar()) cn.Close()
CIBERTEC
CARRERAS PROFESIONALES
14
6. Connection Pooling en ADO .NET Cuando una aplicación se conecta a un servidor de base de datos, lo primero que hace es abrir una conexión con el servidor; lo que resulta ser un proceso costoso: • Desde el punto de vista del cliente, hay que abrir una conexión de red con el servidor, enviarle una cadena de conexión y esperar la confirmación. • Desde el punto de vista del servidor, se recibe una solicitud de conexión, se valida el usuario que desea conectar y se envía al cliente el resultado de la solicitud. El objetivo de Connection Pooling es gestionar, en el cliente, un sistema que almacena conexiones abiertas contra el servidor de base de datos. Para ello, creará listas de conexiones, agrupadas por el par dominio de la aplicación/cadena de conexión. Para habilitarlo usaremos Pooling=true. Al conectarse a un servidor de base de datos, comprueba su pool de conexiones, si existe una que coincida, utilizará la que tiene en el pool; sino creará una nueva conexión. En el siguiente ejemplo, se crean tres objetos SqlConnection, pero solo se necesitan dos grupos de conexión para administrarlos. Using cn As New SqlConnection(“Server=. ;DataBase=NorthWind; uid=sa”) cn.Open() ‘Pool A es creado End Using Using cn As New SqlConnection(“Server=. ;DataBase=Pubs; uid=sa”) cn.Open() ‘Pool B es creado End Using Using cn As New SqlConnection(“Server=. ;DataBase=NorthWind; uid=sa”) cn.Open() ‘La conexión coincide con Pool A End Using
6.1 Adición de conexiones Por cada cadena de conexión única se crea un grupo de conexión; las conexiones se agregan al grupo cuando es necesario, hasta el tamaño máximo del grupo especificado en la propiedad Max Pool Size (100 es el valor predeterminado), y se liberan del grupo cuando se cierran o eliminan.
6.2 Eliminación de conexiones Si la aplicación no cierra ni elimina explícitamente sus conexiones, es mejor asegurarse de que llama claramente a Close y Dispose en las conexiones
7. DBFACTORY CON ADO.NET Ante la necesidad de escribir aplicaciones que puedan trabajar con cualquier tipo de base de datos, siempre se ha recurrido al “modelo de n capas” donde una de ellas, era el proveedor de acceso a datos y se encargaba de abstraer esta tarea, normalmente encapsulada en una librería “.dll” que se cambiaba a voluntad sin que ello supusiese ningún problema para la aplicación. Esta librería, suele contener lo que se denomina un DBFactory, una clase abstracta o conjunto de funciones encargadas de adaptarse a la base de datos que se le indique y obtener datos de forma transparente para su consumidor, esta semana he descubierto como hacerlo con ADO.NET 2.0 sin tener que codificar a penas nada con las clases que “habitan” en System.Data.Common.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
15
En el siguiente ejemplo, vamos a conectarnos a la base de datos DBVentas, administrados por SQL Server, utilizando la clase DBFactory. 1. Defina la cadena de conexión en el app.config.
2. En el formulario, defina las librerías para trabajar con el origen de datos. Imports System.Data.Common Imports System.Configuration.ConfigurationManager
3. Defina el Proveedor de DBfactory para conectarse a SQL Server. Private db As DbProviderFactory = DbProviderFactories.GetFactory(ConnectionStrings("cn").ProviderName)
3. Defina la conexión a la base de datos DBVentas. Dim cn As DbConnection = db.CreateConnection cn.ConnectionString = ConnectionStrings("cn").ConnectionString
LABORATORIO 1.1 ACCESO A DATOS EN UN FORMULARIO WINDOWS FORM, UTILIZANDO EL ASISTENTE En este Laboratorio, presentamos un formulario Windows Forms sencillo que muestra los datos de la tabla artículos en una cuadrícula de datos (DataGridView). 1. Ingrese a Visual Studio 2005 2. Selecciona Files -> New ->Project 3. Elija las siguientes opciones: - En “Project Types” elija “Visual Basic” - En “Templates” elija “WindowsApplication” - En “name” coloque “appFacturacion” - En “Location” coloque “C:\CursoPOOII”
CIBERTEC
CARRERAS PROFESIONALES
16
4. En el Formulario, Agregue un control DataGridView, para realizar la conexión a la base de datos BDFactura, se muestra la lista de tareas tal como se observa en la figura: Permite visualizar la lista de tareas del control
5. En la lista de tareas del DataGridView1 (nombre del control) debemos asignar un origen de datos (Choose Data Source), tal como se muestra en la figura. Desplegar dicha opción; si no tenemos origen de datos, entonces lo añadiremos utilizando la opción Add Project Data Source, tal como se muestra. Clickea para elegir un origen de datos
Clickea para añadir un origen de datos al proyecto
6. Al seleccionar la opción Add Project Data Source, se presenta el asistente de configuración de origen de datos. La primera opción es elegir el tipo de origen de datos Choose a Data Source Type, seleccione la opción Database; luego, presione el botón Next
7. En la segunda ventana del Asistente, permite elegir la conexión de datos Choose Your Data Connection, el cual podemos seleccionar una conexión; en caso de que no haya, presione el botón New Connection.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
17
Presione el botón para crear una nueva conexión
8. Seleccione el origen de datos, el cual será Microsoft SQL Server, tal como se muestra en la figura; luego, presione el botón OK. 9. Al añadir una nueva conexión, se visualiza una ventana para crear la conexión a la base de datos, donde se ingrese el nombre del servidor Server Name, seleccione la autenticación Log on to the Server y seleccione la base de datos Select o enter a DataBase Name. Ingrese el servidor, si utiliza SQL Server 2005, su servidor será: (local)\SQLEXPRESS.
Seleccione la autenticación, que puede ser por Windows o SQL Server.
Seleccione la base de datos de la lista
10. Al crear la conexión, ésta se visualiza en la ventana Choose Your Data Connection, tal como se muestra en la figura, para continuar con el asistente presione el botón Next.
Conexión generada por el asistente.
Presione la opción ConnectionString para visualizar la cadena de conexión.
CIBERTEC
CARRERAS PROFESIONALES
18
11. Creada la conexión, debemos elegir la tabla artículos para realizar la consulta, tal como se muestra en la figura. Se puede observar que junto a la selección de la tabla artículos se creará un DataSet llamado BDFacturaDataSet, para almacenar la estructura de la tabla artículos. Luego, presione el botón Finish.
Seleccione la tabla artículos de la base de datos. Al seleccionar el objeto de base de datos, se creará un DataSet.
12. Al finalizar, se visualiza el formulario con el DataGridView1 configurado con la tabla artículos, luego presione F5 para ejecutar.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
19
LABORATORIO 1.2 ACCESO A DATOS EN UN FORMULARIO WINDOWS FORM, UTILIZANDO CODIGO DE PROGRAMACION En este laboratorio, poblaremos un DataGridView con la información de los clientes de la base de datos DBVentas basada en una cadena select SQL. A continuación, ejecutaremos los pasos para ejecutar la consulta SQL y mostrar los resultados en la cuadrícula. 1. Agregue un nuevo formulario de windows al proyecto 2. Agregue un control Label y un control DatGridView tal como se muestra en la figura.
Control Label
Control DataGridView
3. En la ventana de código, se definirán el namespace para SQL Server, en la parte superior, tal como se muestra en la figura. Imports System.Data.SqlClient
4. Defina, a nivel formulario, la cadena de conexión a la base de datos DBVentas. Dim strcon As String = "server = .; DataBase=DBVentas; Integrated Security=True"
5. Defina, a nivel formulario, el objeto Connection: SqlConnection, donde al inicializar la conexión, pasar la cadena de conexión definida en strcon. Private cn As New SqlConnection(strcon)
6. Programa las sentencias en el Evento Load del Form1, para listar los clientes: a. Definir la instancia del objeto DataAdapter llamado da, ejecutando la sentencia de consulta de la tabla tb_clientes. b. La sentencia SQL se ejecutará en el método SelectCommand y los registros resultantes se almacenará en el DataAdapter da. c. Definir un DataTable llamado tabla. d. Poblar los registros resultantes de DataAdapter (da) en tabla. e. Asignar al origen de datos del DataGridView1 el objeto tabla. f. Ejecutar la aplicación. Dim da As New SqlDataAdapter(Select * From tb_clientes", cn) Dim tabla As New DataTable da.Fill(tabla) Me.DataGridView1.DataSource = tabla
CIBERTEC
CARRERAS PROFESIONALES
20
LABORATORIO 1.3 EJECUTAR UN PROCEDURE EN UN FORMULARIO WINDOWS FORM, UTILIZANDO DBFACTORY PROVIDER En este laboratorio, poblaremos un DataGridView al ejecutar un procedimiento almacenado en la base de datos DBVentas, que visualiza los registros de los proveedores. Los siguientes pasos permitirán ejecutar un procedimiento almacenado. 1. En el Administrador de la base de Datos, defina el procedimiento almacenado en la base de datos. Create Procedure usp_Proveedor As Select * From tb_proveedores
2. Agregue un nuevo formulario de windows al proyecto. 3. Agregue un control Label y un control DatGridView. 4. Agregue en el proyecto un app.config para definir una cadena de conexión a la base de datos DBVentas y defina el proveedor del origen de datos: SqlClient.
5. En la ventana de código, defina las librerías para trabajar con la cadena de conexión en app.config y con DBFactory. Imports System.Data.Common Imports System.Configuration.ConfigurationManager
6. Defina al proveedor DBFactory para conectarse a un origen de datos en SQL Server. Private db As DbProviderFactory = DbProviderFactories.GetFactory(ConnectionStrings("cn").ProviderName)
7. Programe las siguientes sentencias en el evento load del Form1 para ejecutar el procedimiento almacenado: a. Defina un DBConnection llamado cn, asigne en la propiedad ConnectionString el objeto definido en el app.config llamado “cn”. b. Defina un DBCommand llamado cmd. Asigne: en la propiedad Connection la conexión cn, en la propiedad CommandText el nombre del procedure, en la propiedad CommandType el tipo de comando, el cual será un procedimiento almacenado. c. Defina un DbDataAdapter llamado da. d. Asigna en la propiedad SelectCommand del DataAdapter, el comando. e. Defina un DataTable llamado tabla. f. Poblar los registros resultantes de DataAdapter (da) en tabla. g. Asigna al origen de datos del DataGridView1 el objeto tabla.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
21
Dim cn As DbConnection = db.CreateConnection cn.ConnectionString = ConnectionStrings("cn").ConnectionString Dim cmd As DbCommand = cn.CreateCommand cmd.Connection = cn cmd.CommandText = "usp_proveedor" cmd.CommandType = CommandType.StoredProcedure Dim da As DbDataAdapter = db.CreateDataAdapter da.SelectCommand = cmd Dim tabla As New DataTable da.Fill(tabla) Me.DataGridView1.DataSource = tabla
8. Ejecute la aplicación.
Autoevaluación 1. ¿Cuál es la Arquitectura ADO .NET? _______________________________________________________________ _______________________________________________________________ _______________________________________________________________ 2. ¿Cuáles son los proveedores de datos en .NET Framework? _______________________________________________________________ _______________________________________________________________ 3. Defina brevemente los objetos principales de los proveedores de datos _______________________________________________________________ _______________________________________________________________ _______________________________________________________________ 4. Defina brevemente los parámetros de una cadena de conexión _______________________________________________________________ _______________________________________________________________ 5. ¿Qué es el Connection Pooling? _______________________________________________________________ _______________________________________________________________ _______________________________________________________________ 6. ¿Cuáles son los objetos para realizar una conexión utilizando DBFactory _______________________________________________________________ _______________________________________________________________ _______________________________________________________________
CIBERTEC
CARRERAS PROFESIONALES
22
Resumen El proveedor de datos .NET de SQL Server o del proveedor de datos .NET de OLE DB requiere de la instalación de la versión 2.8 de Microsoft Data Access Components. Existen 4 tipos de proveedores de datos: SqlClient, OleDB, ODBC, OracleClient. El objeto DataAdapter o adaptador de datos permite llenar un DataSet y realizar actualizaciones a la base de datos. El objeto DataReader es un lector de datos; el objeto DataSet almacena un conjunto de datos para realizar operaciones de consulta y actualización. La conectarse a una base de datos en SQL Server, se requiere de los siguientes parámetros: Data Source, Inicial Catalog, Integrated Security o User Id. La cadena de conexión es almacenada en un app.config dentro de la etiqueta connectionString. El objeto Command ejecuta sentencias SQL, procedimientos almacenados, funciones, así como sentencias de definición de datos: crear y eliminar tablas. Cuando se ejecuta un Command de actualización, se debe abrir la conexión cn.Open () y al finalizar el proceso cerrar la conexión cn.Close (). La librería DBFactory, es una clase abstracta o conjunto de funciones encargadas de adaptarse a la base de datos que se le indique y obtener datos de forma transparente para su consumidor, esta semana he descubierto como hacerlo con ADO.NET 2.0, codificando mínimamente con las clases que “habitan” en System.Data.Common.
Si desea consultar mas acerca de estos temas puede consultar las siguientes paginas: http://msdn2.microsoft.com/es-es/library/e80y5yhx(VS.80).aspx Referencia a ADO.NET 2.0 http://msdn.microsoft.com/es-es/library/27y4ybxw(VS.80).aspx Referencia a la arquitectura de ADO.NET http://sabia.tic.udc.es/docencia/is/old/2006-2007/docs/transparencias/03ADO.NET.pdf Referencia a ADO.NET, arquitectura, diseño e implementación
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
23
UNIDAD DE APRENDIZAJE
1 SEMANA
2 OPERACIONES DE CONSULTA Y RECUPERACION DE DATOS UTILIZANDO ADO.NET LOGRO DE LA UNIDAD DE APRENDIZAJE Al término de la unidad, los alumnos elaboran aplicaciones Windows .NET que se conectan a un origen de datos utilizando los objetos de ADO.NET para realizar operaciones de consulta y recuperación de datos.
TEMARIO • • • • • •
Arquitectura y componentes de ADO.NET. Administración almacenamiento de una cadena de conexión a un origen datos. Operaciones de consulta sobre un origen de datos. Recuperación de datos utilizando DataAdapter, DataReader y Command. Manejo de TableAdapter, Usando LINQ to SQL. Modificación de datos, manejo de transacciones de datos y excepciones.
de
ACTIVIDADES PROPUESTAS •
Los alumnos utilizan los objetos de ADO.NET: DataAdapter, DataReader y Command para realizar las consultas de datos.
•
Los alumnos definen y ejecutan procedimientos almacenados para consultar información de un origen de datos.
CIBERTEC
CARRERAS PROFESIONALES
24
1
CONEXIÓN CON DATOS Y RECUPERACION EN ADO .NET La principal función de cualquier aplicación de base de datos es conectarse a un origen de datos y recuperar los datos contenidos. Los proveedores de .NET Framework para ADO.NET sirven como puente entre una aplicación y un origen de datos, permitiéndole ejecutar comandos y recuperar datos mediante un DataReader, DataAdapter o un TableAdapter.
2 TRABAJO CON DATAADAPTERS Un DataAdapter se utiliza para recuperar datos de un origen de datos y llenar tablas con un DataSet. El DataAdapter, también, resuelve los cambios realizados en el DataSet de vuelta al origen de datos. Mediante el objeto Connection del proveedor de datos de .NET Framework, DataAdapter se conecta a un origen de datos y utiliza objetos Command para recuperarlos del origen de datos y resolver los cambios a dicho origen. Cada proveedor de datos de .NET Framework incluido en .NET Framework cuenta con un objeto DataAdapter:
Proveedor
Descripción
OleDataAdapter
Proveedor de datos para OLE DB
SqlDataAdapter
Proveedor de datos para SQL Server
OdbcDataAdapter
Proveedor de datos para ODBC
OracleDataAdapter
Proveedor de datos para Oracle
2.1 Forma de llenar un DataSet desde un DataAdapter Un DataSet representa un conjunto completo de datos que incluye restricciones y tablas, así como relaciones entre estas últimas. Dado que DataSet es independiente del origen de datos, puede incluir datos locales de la aplicación, así como datos de otros muchos orígenes. La interacción con los orígenes de datos existentes se controla mediante el DataAdapter. La propiedad SelectCommand del DataAdapter es un objeto Command que recupera datos del origen de datos. El método Fill del DataAdapter se usa para llenar un DataSet con los resultados de la propiedad SelectCommand del DataAdapter. El método Fill acepta como argumentos un DataSet que se debe llenar y un objeto DataTable, o su nombre, que se debe llenar con las filas que devuelve SelectCommand. En el siguiente ejemplo de código se muestra cómo crear un objeto SqlDataAdapter para llenar en el DataSet la lista de Clientes (Customers) de la base de datos Northwind de SQL Server.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
25
'cn sera el Objeto SqlConnection para la Base de Datos BDFactura Dim queryString As String = _ "SELECT CustomerID, CompanyName FROM dbo.Clientes" Dim adapter As New SqlDataAdapter(queryString, cn) Dim customers As DataSet = New DataSet 'poblar los datos en el DataSet y defina una Tabla “Customers” adapter.Fill(customers, "Clientes")
3. TRABAJO CON DATAREADERS El DataReader de ADO.NET recupera secuencias de datos de sólo lectura y sólo avance de una base de datos. Los resultados se devuelven a medida que se ejecuta la consulta y se almacenan en el búfer de red del cliente hasta que se solicitan con el método Read del DataReader. Con el DataReader puede aumentar el rendimiento de la aplicación tanto al recuperar datos en cuanto están disponibles como al almacenar (de forma predeterminada) una fila cada vez en memoria, lo que reduce la sobrecarga del sistema. Cada proveedor de datos de .NET Framework incluido en .NET Framework cuenta con un objeto DataReader:
Proveedor
Descripción
OleDataReader
Proveedor de datos para OLE DB
SqlDataReader
Proveedor de datos para SQL Server
OdbcDataReader
Proveedor de datos para ODBC
OracleDataReader
Proveedor de datos para Oracle
3.1 Recuperación de datos mediante DataReader La recuperación de datos mediante DataReader implica crear una instancia del objeto Command y de un DataReader, para lo cual se llama a Command.ExecuteReader a fin de recuperar filas de un origen de datos. En el ejemplo se muestra cómo se utiliza unSqlDataReader, donde command representa un objeto SqlCommand válido. 'Definir el Objeto CmdReader Dim CmdReader As New SqlCommand 'reader cargara los datos al ejecutar el Metodo ExecuteReader Dim reader As SqlDataReader = CmdReader.ExecuteReader()
El método Read del objeto DataReader permite obtener una fila a partir de los resultados de una consulta. Para tener acceso a cada columna de la fila devuelta, puede pasar a DataReader el nombre o referencia numérica de la columna en cuestión.
CIBERTEC
CARRERAS PROFESIONALES
26
Sin embargo, el mejor rendimiento se logra con los métodos que ofrece el DataReader y que permiten tener acceso a los valores de las columnas en sus tipos de datos nativos (GetDateTime, GetDouble, GetGuid, GetInt32, etc). En el ejemplo de código siguiente se repite por un objeto DataReader y se devuelven dos columnas de cada fila. Dim str As String = "" Dim query As String = _ "SELECT CustomerID, CompanyName FROM dbo.Customers" 'Definir el Objeto CmdReader Dim CmdReader As New SqlCommand(query, cn) Dim reader As SqlDataReader = CmdReader.ExecuteReader() 'Preguntamos si el reader tiene filas If reader.HasRows Then 'Bucle que se ejecuta si se puede leer un registro en reader Do While reader.Read str += reader.GetString(0) + vbTab + reader.GetString(1) Loop End If 'Terminado el proceso cerrar el reader reader.Close()
3.2 Cerrar el DataReader Siempre debe llamar al método Close cuando haya terminado de utilizar el objeto DataReader. Tenga en cuenta que mientras está abierto un DataReader, éste utiliza de forma exclusiva el objeto Connection.
4 TRABAJO CON COMMANDOS Una vez establecida una conexión a un origen de datos, puede ejecutar: Sentencias SQL, Procedimiento Almacenados, Funciones y devolver resultados desde el mismo mediante un objeto Command. Para crear un comando, puede utilizar el constructor Command, que toma argumentos opcionales de una instrucción SQL para ejecutar en el origen de datos, un objeto Connection y un objeto Transaction. También puede crear un comando para una determinada conexión mediante el método CreateCommand del objeto Connection. La instrucción SQL del objeto Command se puede consultar y modificar mediante el uso de la propiedad CommandText. Cada proveedor de datos de .NET Framework incluido en .NET Framework cuenta con un objeto Command:
Proveedor
Descripción
OleDbCommand
Proveedor de datos para OLE DB
SqlCommand
Proveedor de datos para SQL Server
OdbcCommand
Proveedor de datos para ODBC
OracleCommand
Proveedor de datos para Oracle
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
27
4.1 Ejecución de un comando El objeto Command expone varios métodos Execute que puede utilizar para llevar a cabo la acción deseada.
Método
Descripción
ExecuteReader
Los resultados se devuelven en una secuencia de datos para devolver un objeto DataReader.
ExecuteScalar
Retorna valor Singleton.
ExecuteNonQuery
Se utiliza para ejecutar comandos que no retornan filas.
En el siguiente ejemplo de código, se muestra cómo crear un objeto SqlCommand para ver una lista de categorías de la base de datos Northwind de SQL Server. 'cn sera el Objeto SqlConnection para la Base de Datos Northwind Dim cmd As New SqlCommand("Select * from dbo.Categories", cn)
4.2 Ejecución de una consulta que retorne un conjunto de resultados Los objetos Command de ADO .Net tiene un método ExecuteReader el cual permite ejecutar una consulta que retorna uno o más conjunto de resultados. Al ejecutar el método ExecuteReader podemos pasar un parámetro al método, el cual representa la enumeración CommandBehavior, que permite controlar al Command como es ejecutado. A continuación, mostramos CommandBehavior.
la
descripción
de
los
enumerables
del
Valor del CommandBehavior
Descripción
CommandBehavior.CloseConnection
Se utiliza para cerrar la conexión en forma automática, tan pronto como el DataReader es cerrado.
CommandBehavior.SingleResult
Retorna un único conjunto de resultados.
CommandBehavior.SingleRow
Retorna una fila.
En el siguiente ejemplo, se muestra cómo ejecutar una sentencia SQL que visualice el nombre y precio de los artículos almacenados en la base de datos BDFactura. 1. La sentencia SQL a Ejecutar en el comando. Select art_nombre, art_precio From dbo.Articulos
CIBERTEC
CARRERAS PROFESIONALES
28
2. Programe las siguientes sentencias para ejecutar la sentencia sql. Utilice el bloque Using. a. Abra la conexión cn. b. Establecer la estructura Using cmd. c. Defina un DataReader llamado reader. d. Ejecute el Command cmd con el método ExecuteReader e indicar la numeración CommandBehavior.CloseConnection or CommandBehavior.SingleResult. e. Preguntamos si tiene filas el reader (HasRows), procedemos a leer los datos, después de la lectura, cerramos el DataReader. cn.Open() Using cmd As New SqlCommand("Select art_nombre, art_precio From dbo.Articulos", cn) Dim reader As SqlDataReader reader = cmd.ExecuteReader( _ CommandBehavior.CloseConnection Or CommandBehavior.SingleResult) If reader.HasRows Then While reader.Read ListBox1.Items.Add(reader.GetString(0) + vbTab + _ reader.GetDecimal(1).ToString) End While End If reader.Close() End Using
4.3 Ejecución de procedimientos almacenados utilizando Command Los procedimientos almacenados ofrecen numerosas ventajas en el caso de aplicaciones que procesan datos. Mediante los procedimientos almacenados, las operaciones de bases de datos se pueden encapsular en un solo comando, se optimizan para lograr el mejor rendimiento y disfrutan de una seguridad adicional. 'El Command ejecutara un Procedimiento Almacenado Dim cmd As New SqlCommand("usp_Vendedor", cn) 'Establecer la Propiedad CommandType cmd.CommandType = CommandType.StoredProcedure
Aunque es cierto que para llamar a un procedimiento almacenado basta con pasar en forma de instrucción SQL su nombre seguido de los argumentos de parámetros, el uso de la colección Parameters del objeto Command de ADO.NET permite definir más explícitamente los parámetros del procedimiento almacenado, así como tener acceso a los parámetros de salida y a los valores devueltos. Un objeto Parameter se puede crear mediante el constructor Parameter o al llamar al método Add de la colección Parameters de Command. Parameters.Add acepta como entrada argumentos del constructor o cualquier objeto Parameter ya existente. Al establecer como una referencia nula el valor de Value de un objeto Parameter, debe utilizar DBNull.Value. En el caso de parámetros que no sean de entrada (Input), debe asignar a la propiedad ParameterDirection un valor que especifique cuál es el tipo de parámetro: InputOutput, Output o ReturnValue.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
29
Para llamar a un procedimiento almacenado, establezca el CommandType del objeto Command como StoredProcedure. Al asignar el valor StoredProcedure a CommandType, puede utilizar la colección Parameters para definir parámetros. 4.3.1 Ejecutar un procedimiento almacenado con parámetro. 1. Ejecute un procedimiento llamado usp_facturas_cliente CREATE PROCEDURE USP_FACTURAS_CLIENTE @cli char(5) AS Select * from dbo.fac_cabe Where cli_codigo=@cli
2. Defina un objeto SqlCommand llamado cmd el cual ejecutará el procedimiento almacenado “usp_facturas_cliente”, defina la propiedad CommandType a StoreProcedure. Agregue el valor del parámetro @cli. Using cn As New SqlConnection(strcon) Dim cmd As New SqlCommand("usp_facturas_cliente", cn) cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add("@cli",SqlDbType.Char).Value="C0002" ...........
3. Para guardar el resultado del Procedure, se crearán los objetos DataAdapter y DataSet. A continuación, definido el Command, definiremos los objetos que guardarán los registros. ........... Dim da As New SqlDataAdapter da.SelectCommand = cmd Dim ds As New DataSet da.Fill(ds, "Facturas") End Using
CIBERTEC
CARRERAS PROFESIONALES
30
LABORATORIO 2-1 CONSULTA DE DATOS, UTILIZANDO COMMAND En este escenario, se mostrará los registros almacenados en la tabla clientes de la base de datos BDFactura; para lo cual se hará uso del objeto Command, para ejecutar la sentencia SQL, el objeto DataAdapter para recuperar los registros. 1. Ingrese a Visual Studio 2005. 2. Seleccione en el menú Files -> New ->Project. 3. Elija las siguientes opciones de la ventana para crear un nuevo proyecto. - En “Project Types” elija “Visual Basic”. - En “Templates” elija “WindowsApplication”. - En “name” coloque “appFacturacion02. - En “Location” coloque “C:\CursoPOOII”. 2
Diseñe la siguiente interface de usuario como la siguiente figura:
Control Label
Control DataGridView
Objeto Label 1 DataGridView1 3
Propiedad Text
Valor Listado de Clientes
Utilice el Namespace System.Data.SqlClient dentro de la clase Form1; agregar código en el evento load del Form1 para visualizar los clientes al cargar el Form1. Luego, ejecutar el formulario. Using cn As New SqlConnection("Server=(local)\SQLEXPRESS; DataBase=DBVentas; integrated security=true") Using cmd As New SqlCommand("Select* from tb_Clientes", cn) Dim da As New SqlDataAdapter da.SelectCommand = cmd Dim ds As New DataSet da.Fill(ds, "Clientes") Me.DataGridView1.DataSource = ds.Tables("Clientes") End Using End Using
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
31
LABORATORIO 2-2 CONSULTA DE DATOS, UTILIZANDO COMANDOS PARAMETRIZADOS En este escenario desarrollaremos una consulta a las facturas por cliente, donde al seleccionar un cliente dentro de un ComboBox, visualizamos las facturas correspondientes al cliente seleccionado.
1. Agregue un nuevo formulario de Windows al proyecto. Control ComboBox
Control DataGridView
Objeto Label 1 ComboBox1 DataGridView1
Name
Propiedad
Valor
Label1 CboCliente DGFactura
Text
Seleccione un Cliente
2. Cuando necesitamos mostrar en un control de selección: ComboBox o ListBox, una lista de valores provenientes de un campo de una tabla, debemos configurar sus propiedades: Propiedad DataSource DisplayMember ValueMember
Descripción Origen de datos del control. Campo a visualizar. Valor del campo permanecerá oculto.
3. Declare e inicialice el objeto Connection, a nivel clase Form2 Private cn As New SqlConnection("Server=(local)\SQLEXPRESS; DataBase=BDFactura; integrated security=true")
4. En el evento Load Form2, procedemos a cargar el ComboBox CboCliente. Dim cmd As New SqlCommand( _ "Select cli_codigo, cli_nombre from tb_clientes", cn) Dim da As New SqlDataAdapter da.SelectCommand = cmd Dim tabla As New DataTable da.Fill(tabla) Addhandler direcciona Me.CboCliente.DataSource = tabla el evento Me.CboCliente.DisplayMember = "NombreCia" Me.CboCliente.ValueMember = "ClienteID" SelectedIndexChanged Addhandler CboCliente.SelectedIndexChanged, _ del CboCliente al addressof CboCliente_SelectedIndexChanged método.
CIBERTEC
CARRERAS PROFESIONALES
32
5. Definir el método de evento CboCliente_SelectedIndexChanged que permite desencadenar el evento SelectedIndexChanged del CboCliente, donde al seleccionar un cliente visualice las facturas. Private Sub CboCliente_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Consulta con Dim cod As String = CboCliente.SelectedValue parámetro @cli Dim cmd As New SqlCommand( _ "Select * from dbo.fac_cabe Where cli_codigo=@cli", cn) cmd.Parameters.Add("@cli", SqlDbType.Char).Value = cod Dim da As New SqlDataAdapter da.SelectCommand = cmd Dim tabla As New DataTable da.Fill(tabla) Me.DGFactura.DataSource = tabla
Agregar el parámetro @cli en el Command Poblar los datos al DataTable tabla
End Sub
6. Ejecute el formulario y ejecute la selección en el ComboBox CboCliente.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
33
LABORATORIO 2-3 CONSULTA DE DATOS, UTILIZANDO PROCEDURES Y PARÁMETROS En este escenario, desarrollaremos una consulta a las facturas por vendedor y año, donde al seleccionar un vendedor dentro de un ComboBox y un año dentro de un ComboBox, visualizamos las facturas correspondientes al vendedor y año seleccionado. 1. Agregue un nuevo formulario de Windows al proyecto. Control ComboBox CboVendedor Control Button BtnConsulta Control ComboBox CboAño
Control DataGridView DGFactura
Objeto Label1 Label2 ComboBox1 ComboBox2 Button DataGridView1
Name
Propiedad
Valor
Label1 Label2 CboVendedor CboAño BtnConsulta DGFactura
Text Text
Vendedor Año
Text
Consulta
2. Definimos el procedimiento almacenado a ejecutar, donde, en su definición agregamos dos parámetros.
CREATE PROCEDURE USP_FACTURA_YEAR_VENDEDOR @ven char(5), @y int As Select * from fac_cabe Where ven_codigo=@ven and year(fac_fecha)=@y
3. Declaración e inicialización del objeto Connection, a nivel clase Form. Private cn As New SqlConnection("Server=(local)\SQLEXPRESS; DataBase=BDFactura; integrated security=true")
CIBERTEC
CARRERAS PROFESIONALES
34
4. En el evento Load del Form, procedemos a cargar el ComboBox CboVendedor, para lo cual ejecutamos una consulta que recupera los datos de los vendedores. Dim cmd As New SqlCommand( _ "Select Ven_codigo, Ven_nombre from dbo.Vendedor", cn) Dim da As New SqlDataAdapter da.SelectCommand = cmd Dim tabla As New DataTable da.Fill(tabla)
Enlazar el CboVendedor a tabla, enlazamos los datos en el DisplayMember y ValueMember
Me.CboVendedor.DataSource = tabla Me.CboVendedor.DisplayMember = "Ven_nombre" Me.CboVendedor.ValueMember = "Ven_codigo"
5. En el mismo evento Load del Form, procedemos a cargar el ComboBox CboAño, para lo cual ejecutamos una consulta que recupera los datos de los Años facturados. Observamos que los objetos se instancian para ser reutilizados. cmd = New SqlCommand("Select distinct “ + _ “Year(fac_fecha) as y from dbo.fac_cabe", cn) da = New SqlDataAdapter da.SelectCommand = cmd tabla = New DataTable da.Fill(tabla)
Enlazar el CboAño a tabla, enlazamos los datos en el DisplayMember y ValueMember
Me.CboAño.DataSource = tabla Me.CboAño.DisplayMember = "y" Me.CboAño.ValueMember = "y"
6. En el evento Click del botón BtnConsulta se realiza el proceso de selección de las
facturas por año y vendedor seleccionado. En este proceso se ejecuta el Procedure y se añade sus parámetros.
Dim cmd As New SqlCommand("USP_FACTURA_YEAR_VENDEDOR", cn) cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add("@ven", SqlDbType.Char).Value = CboVendedor.SelectedValue cmd.Parameters.Add("@y", SqlDbType.Int).Value = CboAño.SelectedValue Dim da As New SqlDataAdapter da.SelectCommand = cmd Dim tabla As New DataTable da.Fill(tabla) Me.DGFactura.DataSource = tabla
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
35
7. Ejecute el formulario y efectuar la selección.
LABORATORIO 2-4 NAVEGACIÓN DE REGISTROS DE DATOS. En este escenario vamos a navegar por la filas de una tabla de un DataSet, mediante el empleo de la clase CurrencyManager.
¿Qué es el objeto CurrencyManager? El objeto CurrencyManager le permite sincronizar controles enlazados a medida que un usuario examina las filas de una tabla. Por ejemplo, CurrencyManager le permite mostrar las propiedades FirstName y LastName correctas en controles TextBox enlazados diferentes a medida que un usuario examina la tabla clientes. Puede utilizar estos eventos para hacer un seguimiento de cuándo un usuario se mueve por las filas y de cuándo modifica valores de controles enlazados. En este laboratorio describe qué acciones se van a realizar para navegación por los registros de clientes utilizando el objeto CurrencyManager. 1. Agregar un nuevo formulario de Windows al proyecto. Controles TextBox
Controles Button
Objeto Label1 Label2 Label3 Label4 Textbox1 Textbox2 Textbox3 Textbox4 Button1 Button2 Button3 Button4
CIBERTEC
Name
Propiedad
Valor
Label1 Label2 Label3 Label4 Txtcodigo Txtnombre Txtdireccion Txtruc Btnprimero Btnanterior Btnsiguiente Btnultimo
Text Text Text Text Text Text Text Text Text Text Text Text
Codigo Nombre Direccion Ruc
|< < > >|
CARRERAS PROFESIONALES
36
2. Definimos la sentencia SQL, donde visualiza los datos de los clientes. Select cli_codigo, cli_nombre, cli_direccion, cli_ruc from dbo.clientes
3. Declaración e inicialización del objeto Connection, a nivel clase Form. Private cn As New SqlConnection("Server=(local)\SQLEXPRESS; DataBase=BDFactura; integrated security=true")
4. Declarar el objeto CurrencyManager a nivel Form. Private WithEvents myCurrencyManager As CurrencyManager
5. En el evento Load del Form, cargamos el DataSet ds, que permitirá enlazar los datos a los TextBox; luego, especificamos el CurrencyManager de la tabla. Dim daCust As New SqlDataAdapter( _ "Select * from dbo.clientes", cn) Dim ds As New DataSet() daCust.Fill(ds, "Clientes") txtcodigo.DataBindings.Add( _ "Text", ds.Tables!Clientes, "cli_codigo") txtdireccion.DataBindings.Add( _ "Text", ds.Tables!Clientes, "cli_direccion") txtnombre.DataBindings.Add( _ "Text", ds.Tables!Clientes, "cli_nombre") txtruc.DataBindings.Add( _ "Text", ds.Tables!Clientes, "cli_ruc") 'Especificar el CurrencyManager de la tabla Clientes. myCurrencyManager = CType(Me.BindingContext(ds.Tables!Clientes), CurrencyManager)
6. En el proceso de navegación, a cada botón se le agregará sentencias de navegación. En el evento del botón btnprimero, el puntero se ubicará en el primer registro. myCurrencyManager.Position = 0
7. En el evento del botón btnanterior, el puntero se ubicará al registro anterior. If myCurrencyManager.Position > 0 Then 'retroceder una fila. myCurrencyManager.Position -= 1 End If
8. En el evento del botón btnsiguiente, el puntero se ubicará en el registro siguiente. If myCurrencyManager.Position < myCurrencyManager.Count Then 'avanzar una fila. myCurrencyManager.Position += 1 End If
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
37
9. En el evento del botón btnultimo, el puntero se ubicará en el último registro. myCurrencyManager.Position = myCurrencyManager.Count
Autoevaluación
1. Sobre la base del siguiente formulario, seleccione un mes y año desde los controles ComboBox, y al hacer click en el botón consulta, visualice las facturas en el DataGridView que coincidan con el mes y año seleccionado.
2. Construya un formulario de navegación que permita desplazarse y mostrar en los textbox los datos de las facturas al seleccionar un determinado año en un control ComboBox. Debe de enlazar en tiempo de ejecución.
CIBERTEC
CARRERAS PROFESIONALES
38
Resumen En cualquier lenguaje de programación, es necesario una conexión de datos. El DataAdapter tiene 4 metodos: SelectCommand ejecuta operaciones de Consulta, InsertCommand ejecuta operación de Inserción, UpdateCommand ejecuta operaciones de Actualizacion y DeleteCommand ejecuta operaciones de eliminación de registros a la base de datos. Después de configurar el Command, se puede ejecutar. Los Command admiten 4 tipos de métodos: ExecuteReader ejecuta una instrucción SQL o procedimiento de Consulta retornando un conjunto de registros que serán almacenados en un DataReader, ExecuteNonQuery ejecuta una instrucción SQL o procedimiento de actualización retornando el numero de registros afectados, ExecuteScalar ejecuta una instrucción SQL o procedimiento almacenado retornando un valor, ExecuteXMLReader obtiene datos en XML. El DataReader de ADO.NET recupera secuencias de datos de sólo lectura y sólo avance de una base de datos. Los resultados se devuelven a medida que se ejecuta la consulta y se almacenan en el búfer de red del cliente hasta que se solicitan con el método Read del DataReader. Los comandos parametrizados y procedimientos almacenados con parámetros utilizan el objeto parameter para definir un parámetro y cargarlo al objeto command en el método Command.Parameters.Add. Los controles enlazados a datos utilizan la propiedad DataSource; para los controles de lista de datos, utilizan dos propiedades: DisplayMember, que es el campo a visualizar y el ValueMember, que es el valor del Campo a visualizar
. Si desea consultar mas acerca de estos temas puede consultar las siguientes paginas: http://msdn2.microsoft.com/es-es/library/ms254953(VS.80).aspx Página que referencia al tema de Trabajo con comandos http://support.microsoft.com/kb/311543/es Página que referencia al objeto Currency Manager
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
39
UNIDAD DE APRENDIZAJE
1 SEMANA
3 MANEJO DEL TABLEADAPTER, USANDO LINQ TO SQL LOGRO DE LA UNIDAD DE APRENDIZAJE Al término de la unidad, los alumnos elaboran aplicaciones Windows .NET que se conectan a un origen de datos utilizando los objetos de ADO.NET para realizar operaciones de consulta y actualización de datos.
TEMARIO • • • • • •
Arquitectura y componentes de ADO.NET. Administración almacenamiento de una cadena de conexión a un origen datos. Operaciones de consulta sobre un origen de datos. Recuperación de datos utilizando DataAdapter, DataReader y Command. Manejo de TableAdapter, Usando LINQ to SQL Modificación de datos, manejo de transacciones de datos y excepciones.
de
ACTIVIDADES PROPUESTAS •
Los alumnos utilizan el asistente del Visual Studio 2005 para crear los objetos de datos enlazados a un origen de datos.
•
Los alumnos realizan operaciones de consulta y actualización de datos en el TableAdapter.
•
Los alumnos utilizan el Mapeo de datos, LINQ, para conectarse a un origen de datos, para realizar operaciones de consulta y filtro de datos.
CIBERTEC
CARRERAS PROFESIONALES
40
1. TABLEADAPTERS Los TableAdapters proporcionan comunicación entre su aplicación y una base de datos mediante la ejecución de instrucciones SQL y procedimientos almacenados. Los TableAdapter se crean con el Diseñador de DataSet dentro de los conjuntos de datos con establecimiento inflexible de tipos. Se pueden crear con el Asistente para Configuración de TableAdapter, o arrastrando los objetos de base de datos del Explorador de servidores al Diseñador de DataSet. Aunque los objetos TableAdapter se diseñan con el Diseñador de DataSet, las clases TableAdapter generadas no se generan como clases anidadas de DataSet. Se encuentran en un espacio de nombres separado y específico para cada conjunto de datos. Para tener acceso a un TableAdapter mediante programación, debe declarar una nueva instancia del TableAdapter. Dim Ds As New DsFactura Dim ArticuloTableAdapter As New _ DsFacturaTableAdapters.ArticulosTableAdapter() ArticuloTableAdapter.Fill(Ds.Articulos)
A diferencia de los DataAdapters, los TableAdapter pueden contener varias consultas que rellenan las tablas de datos asociadas. Puede definir tantas consultas para un TableAdapter como requiera la aplicación, con tal de que cada consulta devuelva datos que cumplan el mismo esquema que la tabla de datos asociada. Por ejemplo, si la aplicación contiene una tabla de artículos, puede crear una consulta para rellenar la tabla con todos los artículos cuyo código sea igual a un parámetro @cod y otra consulta para rellenar la tabla con todos los artículos.
Consulta principal del esquema de la tabla
Consulta adicionales que retornar diferentes vistas
El nombre asignado a un TableAdapter en el momento de su creación se basa en el nombre de la tabla con la que está trabajando. A continuación, se muestran los métodos y propiedades de TableAdapter más utilizados:
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
41
Miembro
Descripción
TableAdapter.Fill
Rellena la tabla de datos asociada del TableAdapter con los resultados del comando SELECT del TableAdapter.
TableAdapter.Update
Devuelve los cambios a la base de datos.
TableAdapter.GetData
Devuelve una nueva DataTable con datos.
TableAdapter.Insert
Crea una nueva fila en la tabla de datos.
TableAdapter.ClearBeforeFill
Determina si se vacía una tabla de datos antes de llamar a uno de los métodos Fill.
1.1 UTILIZANDO EL ASISTENTE PARA CONFIGURAR CONSULTAS DENTRO DE UN TABLEADAPTER El Asistente para la configuración de consultas de TableAdapter ayuda a crear y editar las consultas adicionales que se pueden agregar a TableAdapters. Una consulta de TableAdapter es cualquier consulta SQL válida o cualquier procedimiento almacenado que devuelve datos que satisfacen el mismo esquema que la tabla de datos asociada de TableAdapter o un valor escalar. Para iniciar el Asistente. 1. Abra su conjunto de datos en el Diseñador de DataSet.
Seleccione el Item DataSet Asignarle un Nombre: DsFactura
2. o o
Si está creando un nuevo TableAdapter: Se puede Arrastrar del ToolBox al DataSet: DsFactura. Haciendo click derecho en el DataSet DsFactura, seleccione la opcion Add TableAdapter. Permite agregar un TableAdapter.
CIBERTEC
CARRERAS PROFESIONALES
42
3. En la página Elija la conexión de datos, seleccione o cree la conexión que utilizará la consulta, al seleccionar Nueva Conexión, deberá indicar el servidor, autenticación y base de datos, presione el botón OK. Crear una Nueva Conexión
Establece la conexión: • servidor • autenticación y • base de datos
4. En la página Elija un tipo de comando, seleccione entre los métodos siguientes para obtener datos de la base de datos: o Usar instrucciones SQL permite escribir una instrucción SQL para seleccionar los datos de la base de datos. o Crear un nuevo procedimiento almacenado - El asistente crea un nuevo procedimiento almacenado (en la base de datos) según la instrucción SELECT especificada. o Usar procedimientos almacenados existentes - Seleccione esta opción para ejecutar un procedimiento almacenado existente.
Al seleccionar SQL Statement, en la siguiente ventana definir Select.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
43
5. En la página Elegir los metodos que se van a generar, proporciona las opciones para seleccionar métodos genera el asistente para la consulta. • Rellenar un DataTable.- Crea un método para rellenar la tabla de datos. El usuario pasa el nombre de la tabla de datos como un parámetro al llamar a este método para llenar la tabla de datos con los datos devueltos. También, puede cambiar el nombre predeterminado en el cuadro Nombre de método. • Devolver un DataTable.- Crea un método para devolver una tabla de datos llena. También puede cambiar el nombre predeterminado en el cuadro Nombre de método.
Método Fill, para llenar los datos.
Función GetData, retorna los registros.
6. Al finalizar se creará un TableAdapter, con sus métodos Fill(), GetData().
2
ENLACE DE UNA FUENTE DE DATOS EN VISUAL STUDIO Visual Studio proporciona herramientas en tiempo de diseño para trabajar con objetos personalizados. El único requisito para que los objetos personalizados trabajen con las herramientas de diseño de datos de Visual Studio es que deben contar al menos con una propiedad pública. No se precisa ningún constructor ni atributo concreto para que los objetos personalizados trabajen con herramientas como la ventana Orígenes de datos. En este escenario se muestra cómo crear objetos que contengan datos de clientes y facturas, y crear a continuación un origen de datos de objeto basado en estos objetos.
CIBERTEC
CARRERAS PROFESIONALES
44
2.1 MÉTODO DE AÑADIR UN DATASET AL PROJECTO 1. En la opción Menu Project Add New Item. 2. Selecione la opción DataSet, asignarle el Nombre Facturación.xsd, presione el botón Add.
2.2 CREACIÓN DE UNA CONEXIÓN A LA BASE DE DATOS BDFACTURA 1. En la opción Menu View click en Server Explorer 2. En el Server Explorer, cree una conexión a la Base de Datos: click derecho a DataConnections, seleccione Add Connection…. 3. Cree la conexión a la base de datos BDFactura de SQL SERVER.
2.3 CREACIÓN DE LA TABLA CLIENTES 1. Expanda la Data Connection y expanda el Nodo Tables. 2. Arrastre la tabla Clientes del Server Explorer al Diseñador del DataSet; una tabla clientes y clientesTableAdapter son añadidos al DataSet.
2.4 CREACIÓN DE TABLA FACTURAS 1. Arrastre la tabla Fac_ al Diseñador del DataSet; la tabla fac_cabe y fac_cabeTableAdapter son añadidos. 2.5 CREACIÓN DE DATARELATIONS DENTRO DEL DATASET 1. Arrastre un objeto relation desde el ToolBox del DataSet hacia la tabla hija de la relación (Fac_cabe).
2. Seleccione la tabla Parent (clientes), verifique la tabla Chile (fac_cabe), se visualizan las columnas a relacionar. En tipo de relación a crear es Relation Only, significa que sólo es consulta entre ambas tablas; luego, presione el botón OK.
3. Al presionar el botón OK se creará la relación, en la cual aparecerá en el diseñador entre las dos tablas.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
45
2.6 FORMA DE POBLAR UN DATASET CON DATOS UTILIZANDO UN TABLEADAPTER Para poblar un DataTable utilizando un TableAdapter, ejecute el método Fill del TableAdapter para cargarlo hacia la tabla. En el Load del Form, poblar la tabla clientes del DataSet Facturación, utilizar el método Fill del TableAdapter a la tabla clientes y muestre los datos en el DataGridView.
Dim ds As New Facturacion Dim cli As New FacturacionTableAdapters.ClientesTableAdapter cli.Fill(ds.Clientes) Me.DataGridView1.DataSource = ds.Clientes
3 LINQ PARA .NET Se conoce como LINQ a un Lenguaje Integrado de Consultas (Language Integrated Query). Nos va a permitir poder manipular mejor la información dentro de nuestras aplicaciones. Se basa en varias funcionalidades, tales como colecciones que pueden incluir arreglos, clases, enumerables, XML y base de datos. El proyecto LINQ usa características de la versión 2.0 del .NET Framework, nuevos ensamblados relacionados con LINQ, y extensiones para los lenguajes C# y Visual Basic .NET. Microsoft ha distribuido una versión previa del LINQ, consistente de estas bibliotecas y compiladores para C# 3.0 y Visual Basic 9. Otros lenguajes, como F# y Nemerle, han anunciado brindar soporte preliminar. La arquitectura LINQ es el siguiente:
CIBERTEC
CARRERAS PROFESIONALES
46
3.1 LINQ to SQL LINQ to SQL es una implementación de O/RM (object relational mapping, mapeador de objetos relacionales) que viene con la versión 2008 del .NET Framework, y permite modelar bases de datos relacionales con clases de .NET. Podemos consultar bases de datos con LINQ, así como actualizar/añadir/borrar datos de ellas. Hay dos herramientas disponibles para generar automáticamente un modelo de Visual Basic o C# a partir de los metadatos de una base de datos existente: • El Diseñador relacional de objetos proporciona una interfaz de usuario completa para ayudarle a generar un modelo de objetos LINQ to SQL. • Herramienta de línea de comandos SQLMetal. 3.1.1 Diseñador relacional de objetos El Diseñador relacional de objetos proporciona una superficie de diseño visual para crear clases de entidad y asociaciones (relaciones) de LINQ to SQL basadas en los objetos de una base de datos. El Diseñador relacional de objetos se usa para crear un modelo de objetos en una aplicación que se asigna a los objetos de una base de datos. Genera una clase DataContext con establecimiento inflexible de tipos, que se usa para enviar y recibir datos entre las clases de entidad y la base de datos. El Diseñador relacional de objetos también proporciona la funcionalidad para asignar los procedimientos almacenados y funciones a los métodos de DataContext con el fin de devolver datos y rellenar las clases de entidad. Por último, el Diseñador relacional de objetos permite diseñar relaciones de herencia entre las clases de entidad.
3.1.2 Entendiendo la clase DataContext Visual Studio genera clases .NET para representar las entidades y las relaciones de la base de datos que hemos modelado.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
47
Por cada archivo añadido a nuestra solución por el diseñador LINQ to SQL también se generará una clase DataContext. Esta clase es a través de la cual realizaremos las consultas a las entidades de nuestra base de datos. Tendrá propiedades que representarán a cada tabla que hemos modelado, así como métodos para cada procedimiento almacenado que añadiremos.
La clase tb_empleados, que representa a la tabla tb_empleados
3.1.3 Consultando datos sobre la base de datos LINQ to SQL, admite toda la funcionalidad clave que puede esperar un programador de SQL. Puede consultar, insertar, actualizar y eliminar información en las tablas. En la selección, basta con que escriba una consulta LINQ en su propio lenguaje de programación y, después, la ejecuta para recuperar los resultados. LINQ to SQL convierte todas las operaciones necesarias en las operaciones SQL con las que está familiarizado. Una vez que hemos modelado nuestra base de datos con el diseñador de LINQ to SQL, podemos escribir código fácilmente para trabajar con él. Por ejemplo: listar los clientes y visualizarlos en el DataGridView. Dim db As New DataDBVentasDataContext Dim cliente = From c In db.tb_clientes Me.DataGridView1.DataSource = cliente
CIBERTEC
CARRERAS PROFESIONALES
48
LABORATORIO 3.1 MANEJO DE CONSULTA EN UN TABLEADAPTER En este escenario usted creará un TableAdapter, donde creará una consulta sql que permita visualizar los pedidos entre dos fechas, además visualice la cantidad de facturas resultantes del proceso. 1. Ingrese a Visual Studio 2005. 2. Seleccione File->New->Project. 3. Elija las siguientes opciones: - En “Proyect Types” elija “Visual Basic”. - En “Templates” elija “WindowsApplication”. - En “Name” coloque “appFacturacion5”. - En “Location” coloque “C:\CursoPOOII ». 4. Dentro de la aplicación añadir un item de tipo DataSet asígnele el nombre DBVentasDataSet. 5. Agregue un TableAdapter de la tabla tb_pedidoscabe. 6. A continuación, añada un procedimiento almacenado: click derecho en el TableAdapter y seleccione Add Query tal como se muestra en la Figura.
7. En la página Elija un tipo de comando seleccione la opción: Usar instrucción SQL, presione Next.
8. En la página Elija un tipo de Consulta seleccione la primera opción: SELECT which return rows, esta opción permite retornar un conjunto de filas, presione el botón Next.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
49
9. En la página Especifique una instrucción Select de SQL, defina la sintaxis del procedimiento almacenado: Select * From tb_pedidoscabe Where fechapedido between @f1 and @f2. Luego presione el botón Next. 10. Asigne un nombre a la instrucción FillbyFechas, luego presione el boton Finish.
11. A continuación proceda a diseñar el formulario:
Objeto Label1 Label2 DateTimePicker1 DateTimePicker2 Button1 DataGridView1
Name Label1 Label2 DtFecha1 DtFecha2 BtnConsulta DGFacturas
Propiedad Text Text Format Format Text
Valor Fecha 1 Fecha 2 Short Shor Consulta
12. A nivel Clase Form, defina el objeto DataSet: ds y el objeto TableAdapter fac_Adapter. Private Ds As New DBVentaDataSet Private Pedido As New DBVentaDataSet.tb_pedidoscabeTableAdapter
13. Para listar todas las facturas en el evento Load del Formulario se cargará al DataTable fac_cabe a través del método Fill del TableAdapter y luego visualice los datos. Pedido.Fill(Ds.Fac_cabe) Me.DGFacturas.DataSource = Ds.tb_pedidoscabe
CIBERTEC
CARRERAS PROFESIONALES
50
14. Para listar las facturas entre dos fechas, en el evento click del botón consulta, se ejecutará el método FillBy con sus dos parámetros de fecha, que representa al Procedure creado: usp_facturas_byfechas, para cargarlo al DataTable y, luego, visualizar los datos. Dim f1 As Date = Me.DtFecha1.Value.ToShortDateString Dim f2 As Date = Me.DtFecha2.Value.ToShortDateString Pedido.FillByFechas(Ds.tb_pedidoscabe, f1, f2) Me.DGFacturas.DataSource = Ds.tb_pedidoscabe
15. Ejecute y realice las pruebas.
LABORATORIO 3.2 RELACIONES ENTRE TABLEADAPTER En este escenario, vamos a realizar un consulta entre los clientes y sus pedidos, donde al seleccionar un cliente, visualizamos los pedidos asociada al cliente seleccionado. Para ello creamos un TableAdapter para los clientes y estableceremos la relación entre las tablas del DataSet. 1. En el DataSet: DBVentasDataSet Agregue un TableAdapter llamado tb_clientes, el cual contenga todos los campos de dicha tabla. 2. Creado el TableAdapter para tb_clientes, establezca la relación entre las tablas, que solo sea de tipo relación, el nombre de la relación será: Clientes_Ped_cabe. Relación: Clientes_Pec_cabe
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
51
3. Diseñe el Formulario.
Objeto Label1 Label2 DataGridView1 DataGridView2
Name Label1 Label2 DGCliente DGFactura
Propiedad Text Text
Valor Clientes Facturas
4. Declare a nivel Clase Form el DataSet y los TableAdapter de clientes y facturas. Private Ds As New DBVentasDataSet Dim Cli_TableAdapter As New _ DBVentasDataSetTableAdapters.tb_ClientesTableAdapter Dim Fac_TableAdapter As New _ DBVentasDataSetTableAdapters.tb_pedidoscabeTableAdapter
5. En el evento Load del Formulario, cargue los Tables de las tablas clientes y fac_cabe con los TableAdapter, muestre los clientes en el DataGridView: DGCliente. Cli_TableAdapter.Fill(Ds.tb_Clientes) Fac_TableAdapter.Fill(Ds.tb_pedidoscabe) Me.DGCliente.DataSource = Ds.tb_Clientes
6. En el evento CellCllick del DataGridView DGCliente, al seleccionar un cliente, visualice sus facturas; seleccione una fila del cliente y capture el indice de la fila seleccionada: DGCliente.CurrentRow.Index, y utilizando un DataView y un DataRowView cree la vista hija (ChildView). Dim i As Integer = Me.DGCliente.CurrentRow.Index Dim dv As DataView = Ds.tb_Clientes.DefaultView Dim drv As DataRowView = dv(i) Me.DGFactura.DataSource = _ drv.CreateChildView("Clientes_Ped_cabe")
7. Guarde la aplicación y ejecute. Pruebe los resultados.
CIBERTEC
CARRERAS PROFESIONALES
52
LABORATORIO 3.3 EJECUTAR UN PROCEDIMIENTO ALMACENADO UTILIZANDO UN TABLAADAPTER En este escenario, vamos a ejecutar un procedimiento almacenado de consulta que liste los pedidos de un año seleccionado. 1. Defina el procedimiento almacenado en la base de datos llamado usp_pedidos_year.
2. Arrastre el procedimiento almacenado usp_pedidos_year al DataSet: DBVentasDataSet, tal como se muestra. Método Fill y GetData que define el parámetro @y
3. Diseñe el formulario de la consulta.
Objeto Label Label TextBox Button DataGridView
Name Label1 Label2 txtAño BtnConsulta DataGridView1
CARRERAS PROFESIONALES
Propiedad Text Text
Valor Consulta de Pedidos por Año Año
Text
Consulta
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
4.
53
Declare a nivel Clase Form el DataSet y los TableAdapter de clientes y facturas Private Ds As New DBVentasDataSet
-
Private pedidos As New _ - DBVentasDataSetTableAdapters.usp_pedidos_yearTableAdapter
-
5.
En el evento Click del Button BtnConsulta, ejecute el método Fill de pedidos donde definimos la tabla usp_pedidos_year y el valor del año: txtaño.text. Visualice los registros de la tabla en el DataGridView1. pedidos.Fill(Ds.usp_pedidos_year, Val(TXTAÑO.Text)) Me.DataGridView1.DataSource = Ds.usp_pedidos_year
6.
Guarde la aplicación y ejecute. Al ingresar un año desde el control TxtAño, al presionar el botón CONSULTA, se visualiza los pedidos.
LABORATORIO 3.4 MANEJO DE CONSULTAS UTILIZANDO LINQ to SQL En este escenario, vamos a realizar la consulta de los pedidos por un empleado seleccionado. Para ello vamos a utilizar LINQ to SQL para realizar la consulta de los pedidos. 1. Agregue un nuevo elemento en el proyecto de Windows. 2. Seleccione la plantilla Clases de LINQ to SQL, asigne el nombre DataVentas.dbml Seleccione la plantilla para el manejo de las tablas como clases.
CIBERTEC
CARRERAS PROFESIONALES
54
3. Desde el explorador de servidor arrastre las tablas hacia el diseñador llamado DataVentas.dbml, tal como se muestra.
4. Para establecer la relación entre las clases, agregue una Asociación. En el editor de asociaciones seleccione: • Clase primaria la tabla tb_empleados y • Clase secundaria la tabla tb_pedidoscabe. En la sección propiedades de la asociación, elija el campo IdEmpleado para ambas propiedades; luego presione el botón Aceptar para generar la asociación.
5. A continuación diseñe el Formulario de la consulta.
Objeto Label
Name Label1
Propiedad Text
Label ComboBox Button DataGridView
Label2 ComboBox1 BtnConsulta DataGridView1
Text
Valor Consulta de Pedidos por Empleado Empleado
Text
Consulta
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
55
6. A continuación defina la instancia de DataVentasDataContext a nivel Formulario. Private Data As New DataVentasDataContext
7. En el evento Load del Formulario, declare la variable empleado para definir los empleados desde Data. Cargue los empleados en el ComboBox1. Dim empleado = From emp In Data.tb_empleados Me.ComboBox1.DataSource = empleado Me.ComboBox1.DisplayMember = "Nombre" Me.ComboBox1.ValueMember = "IDempleado"
8.
En el evento Click del button BtnConsulta, declare la variable pedidos para definir la clase tb_pedidoscabe desde el DataVentasDataContext Data y realizar la consulta de pedidos (p) por empleado seleccionado. Dim pedidos = From p In Data.tb_pedidoscabe _ Where p.IdEmpleado=ComboBox1.SelectedValue.toString Select p Me.DataGridView1.DataSource = pedidos
9. Guarda la aplicación y ejecute. Al seleccionar un empleado desde un ComoBox, listamos los pedidos.
LABORATORIO 3.5 MANEJO DE CONSULTA DE PEDIDOS ENTRE FECHAS UTILIZANDO LINQ to SQL En este escenario, vamos a realizar la consulta de los pedidos entre dos fechas ingresadas. Para ello vamos a utilizar en DataConText DataVentasDataContext. 1. Diseña el formulario.
CIBERTEC
CARRERAS PROFESIONALES
56
Objeto Label
Name Label1
Propiedad Text
Label Label TextBox TextBox Button DataGridView
Label2 Label3 TxtFecha1 TxtFecha2 BtnConsulta DataGridView1
Text Text
Valor Consulta de Pedidos entre Fechas Fecha 1 Fecha 2
Text
Consulta
2. A continuación defina la instancia de DataVentasDataContext a nivel Formulario Private Data As New DataVentasDataContext
3. En el evento Click del button BtnConsulta, declare la variable pedidos para definir la clase tb_pedidoscabe desde el DataVentasDataContext Data y realizar la consulta de pedidos (p) entre dos fechas. Dim f1 As Date = CDate(TXTFECHA1.Text) Dim f2 As Date = CDate(TXTFECHA2.Text) Dim pedidos = From p In data.tb_pedidoscabe _ Where p.FechaPedido >= f1 And p.FechaPedido New->Project 3. Elija las siguientes opciones: - En “Proyect Types” elija “Visual Basic” - En “Templates” elija “WindowsApplication” - En “Name” coloque “appFacturacion4” - En “Location” coloque “C:\CursoPOOII” 4. Diseño del Formulario:
5. Defina el Namespaces: System.Data.SqlClient. 6. Defina e inicialice la cadena de conexión a nivel Class Form, el objeto DataSet, que almacenará las tablas. Private cn As New SqlConnection("Server=(local)\SQLEXPRESS; DataBase=DBVentas; integrated security=true") Private ds As New DataSet
7. En el Load del formulario realizar las siguientes operaciones: a. Cargar las tablas clientes y pedidos utilizando el DataAdapter. b. Poblar los registros del DataAdapter al DataSet. c. Enlazar el Listbox1, con la tabla clientes. d. Definir la relación entre las tablas y añadir la relación al DataSet. 'Manejo de DataAdapter Dim da As New SqlDataAdapter("Select * from tb_clientes", cn) da.Fill(ds, "Clientes") ds.Tables("clientes").PrimaryKey = _ New DataColumn() {ds.Tables("clientes").Columns(0)} da = New SqlDataAdapter("Select * from tb_pedidoscabe",cn) da.Fill(ds, "pedidos") 'Enlazar el Listbox1 Me.ListBox1.DataSource = ds.Tables("clientes") Me.ListBox1.DisplayMember = "NombreCia" Me.ListBox1.ValueMember = "IdCliente" 'Establecer la Relacion entre las Tablas Dim drel As New DataRelation( _ "r1", ds.Tables("clientes").Columns("IdCliente"), _ ds.Tables("facturas").Columns("IdCliente")) 'Agregar la relacion ds.Relations.Add(drel)
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
95
8. En el click del Listbox, mostramos las facturas según el cliente seleccionado: a. Capturar el índice de la fila seleccionada: Listbox1.SelectedIndex. b. Definir un Dataview de la tabla clientes. c. Definir un DataRowView. d. A través del método CreateChildView (nombre de la relación) del DataRowView se capturan las filas de fac_cabe las cuales se visualizan en el DataGrid1. Dim i As Integer = ListBox1.SelectedIndex Dim dv As New DataView(ds.Tables("clientes")) Dim drv As DataRowView = dv(i) Me.DataGridView1.DataSource = drv.CreateChildView("r1")
9. Guarde su aplicación y ejecute. Compruebe el resultado.
LABORATORIO 5.2 ACTUALIZACIÓN DE DATOS, UTILIZANDO EL DATAADAPTER En este escenario, se implementara un formulario para realizar el mantenimiento de los vendedores de la base de datos DVentas. A través de este ejemplo utilizaremos los métodos del DataAdapter para la actualización de datos 1. Agregar un formulario al proyecto y diseñarlo.
Objeto Label1 Label2 Label3 Label4 Textbox1 Textbox2 Textbox3 Textbox4 Button1 Button2 Button3 Button4 DataGridView1
CIBERTEC
Name Label1 Label2 Label3 Label4 Txtcodigo Txtnombre Txtfono Txtdireccion BtnLimpiar BtnGrabar BtnActualizar BtnEliminar DGVendedor
Propiedad Text Text Text Text Text Text Text Text Text Text Text Text
Valor Codigo Nombre Teléfono Direccion
Limpiar Grabar Actualizar Eliminar
CARRERAS PROFESIONALES
96
2. Defina el Namespace y la cadena de conexión 3. Defina la función DataArticulos que retorne los artículos. Function DataVendedor() As DataTable Dim da As New SqlDataAdapter("Select*fron tb_vendedor",cn) Dim t As New DataTable da.Fill(t) Return t End Function
4. En el evento Load del Form, llenar los datos en DGVendedor. Me.DGVendedor.DataSource = DataVendedor()
5. Para navegar por los registros del DataGridView DGVendedor y al seleccionar un registro se visualice en los Textboxes, se deberá programar en el evento CellClick. With DGVendedor.CurrentRow txtcodigo.Text = .Cells(0).Value txtnombre.Text = .Cells(1).Value txtfono.Text = .Cells(2).Value txtdireccion.Text = .Cells(3).Value End With
6. En el evento click del botón actualizar, modificamos los datos de un vendedor seleccionado: a. Capture el índice de la fila seleccionada. b. Defina un DataAdapter de tipo UpdateCommand. c. Defina sus parámetros. d. Crea un DataRow de la fila seleccionada. e. Aplique el Update del DataAdapter a la tabla. Dim i As Integer = Me.DGVendedor.CurrentRow.Index Dim da As New SqlDataAdapter("Select * from tb_Vendedor", cn) da.UpdateCommand = New SqlCommand("Update tb_Vendedor Set ven_nombre=@nom, ven_telefono=@f, ven_direccion = @d Where ven_codigo=@cod", cn) With da.UpdateCommand.Parameters .Add("@nom", SqlDbType.VarChar, 30, "ven_nombre") .Add("@f", SqlDbType.Char, 8, "ven_telefono") .Add("@d", SqlDbType.VarChar, 60, "ven_direccion") Dim par As SqlParameter = .Add("@cod", SqlDbType.Char) par.SourceColumn = "ven_codigo" par.SourceVersion = DataRowVersion.Original End With Dim dt As New DataTable da.Fill(dt) Dim row As DataRow = dt.Rows(i) row("ven_nombre") = txtnombre.Text row("ven_telefono") = txtfono.Text row("ven_direccion") = txtdireccion.Text da.Update(dt) Me.DGVendedor.DataSource = ds1
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
97
7. En el evento click del botón grabar, insertaremos un nuevo vendedor: a. Defina un DataAdapter de tipo InsertCommand, defina sus parámetros. b. Cree un DataRow, definir de tipo NewRow, y le agregamos sus valores. c. Añada la nueva fila a la tabla. d. Aplicamos el Update del DataAdapter a la tabla y visualizamos los registros. ¿Cómo evaluaría si el código del vendedor se va a duplicar? Dim da As New SqlDataAdapter("Select * from tb_Vendedor", cn) da.InsertCommand = New SqlCommand("Insert Into tb_Vendedor(ven_codigo,ven_nombre,ven_telefono,ven_direccion) Values(@cod, @nom, @f, @dir)", cn) With da.InsertCommand.Parameters .Add("@cod", SqlDbType.Char, 5, "ven_codigo") .Add("@nom", SqlDbType.VarChar, 30, "ven_nombre") .Add("@f", SqlDbType.VarChar, 8, "ven_telefono") .Add("@dir", SqlDbType.VarChar, 60, "ven_direccion") End With Dim dt As New DataTable da.Fill(dt) Dim row As DataRow = dt.NewRow row("ven_codigo") = txtcodigo.Text row("ven_nombre") = txtnombre.Text row("ven_telefono") = txtfono.Text row("ven_direccion") = txtdireccion.Text dt.Rows.Add(row) da.Update(dt) Me.DGVendedor.DataSource = dt
8. Aplique el concepto para eliminar un registro seleccionado 9. Guarde su aplicación y ejecútela.
LABORATORIO 5.3 ACTUALIZACIÓN DE DATOS, UTILIZANDO EL DATASET En este escenario, se implementará un formulario para realizar el mantenimiento de los artículos de la base de datos BDFactura. 1. Agregue un formulario al proyecto y diséñelo.
CIBERTEC
CARRERAS PROFESIONALES
98
Objeto Label1 Label2 Label3 Label4 Label5 Textbox1 Textbox2 Textbox3 Textbox4 Textbox5 Button1 Button2 Button3 Button4 Button5 DataGridView1
Name Label1 Label2 Label3 Label4 Label5 Txtcodigo Txtdescripcion Txtunidad Txtprecio Txtstock BtnLimpiar BtnBuscar BtnGrabar BtnModificar BtnEliminar DGArticulos
Propiedad Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text
Valor Codigo Descripcion Unidad Precio Stock
Limpiar Buscar Grabar Modificar Eliminar
2. Defina el NameSpace, su conexión y un DataTable. Private cn As New SqlConnection("Server=(local)\SQLEXPRESS; DataBase=DBVentas; integrated security=true") Dim dt As New DataTable
3. En el evento Load del Form, defina el DataTable y una clave primaria. Dim da As New SqlDataAdapter("Select*from tb_productos",cn) da.Fill(dt) dt.PrimaryKey = New DataColumn() {dt.Columns(0)} Me.DGArticulos.DataSource = dt
4. Al seleccionar una fila en el DataGridView, mostrar sus datos, donde haremos una búsqueda de la fila por su código. Dim row As DataRow = dt.Rows.Find( _ Me.DGArticulos.CurrentRow.Cells(0).Value) txtcodigo.Text = row(0) txtdescripcion.Text = row(1) txtunidad.Text = row(2) txtprecio.Text = row(3) txtstock.Text = row(4)
5. En el evento click del botón grabar, agregar un nuevo artículo. Dim Row As DataRow = dt.NewRow Row(0) = txtcodigo.Text Row(1) = txtdescripcion.Text Row(2) = txtunidad.Text Row(3) = Val(txtprecio.Text) Row(4) = Val(txtstock.Text) dt.Rows.Add(Row)
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
99
6. En el evento click del botón buscar, ubique un registro por su código, si lo ubica llenará los TextBox. Dim Row As DataRow = dt.Rows.Find(txtcodigo.Text) If Row Is Nothing Then MessageBox.Show("No Existe") Else txtdescripcion.Text = Row(1) txtunidad.Text = Row(2) txtprecio.Text = Row(3) txtstock.Text = Row(4) End If
7. En el evento click del botón eliminar, se ejecuta el proceso de borrar un registro seleccionado. Dim row As DataRow Row = dt.Rows.Find(Me.DGArticulos.CurrentRow.Cells(0).Value) dt.Rows.Remove(row)
8. En el evento click del botón modificar, se ejecutará en proceso donde se cambiarán los datos del artículo seleccionado. Se observa que no se actualiza el código del artículo. Dim row As DataRow row = dt.Rows.Find(Me.DGArticulos.CurrentRow.Cells(0).Value) row(1) = Me.txtdescripcion.Text row(2) = Me.txtunidad.Text row(3) = Val(txtprecio.Text) row(4) = Val(txtstock.Text)
9. Pinte el botón Actualizar Datos, el cual actualizará los datos del DataTable, donde evalúa, primero, si no tiene errores actualizará los cambios utilizando el método AcceptChanges, caso contrario, visualiza los errores y deshace la operación a través del método RejectChanges. If Not dt.HasErrors Then dt.AcceptChanges() Else Dim str As String = "" For Each row As DataRow In dt.GetErrors str = str + row.RowError + vbCrLf Next MessageBox.Show(str) dt.RejectChanges() End If
CIBERTEC
CARRERAS PROFESIONALES
100
10. Guarde el proyecto y ejecute para realizar las pruebas.
Pregunta: ¿Cómo pasar los datos actualizados en el DataSet a la base de datos?, investigue acerca del CommandBuilder. Tarea de Investigación.
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
101
Autoevaluación 1. ¿Cuál es la Arquitectura del DataSet? _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ 2. ¿Cómo se agrega columnas, cómo se define un campo Unique y un Primary Key? _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ 3. ¿Cuáles son los métodos del DataAdapter? Explique brevemente. _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ 4. Explique el estado y la versión de una fila. _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ _____________________________________________________________ 5. ¿Qué es un DataView? Explique su método de ordenamiento y filtro. _____________________________________________________________ _____________________________________________________________ _____________________________________________________________
CIBERTEC
CARRERAS PROFESIONALES
102
Resumen El modelo de datos desconectados, está representado por el DataSet, el cual está conformado por DataTable Collection, DataRelation Collection, Primary Key, Constraint. Un DataTable se puede trabajar dentro o fuera del DataSet; se le puede agregar columnas, definir constraint: UniqueConstraint y ForeignKeyConstraint. Un DataRelation establece la relación entre dos tablas: principal y la hija; al generar un DataRelation, está se agrega al DataSet y crea, por defecto, un Constraint Unique y ForeignKey. En un DataAdapter, los datos son actualizados a través de sus cuatro métodos: InsertCommand, UpdateCommand, DeleteCommand y SelectCommand, los que afectan directamente al origen de datos, utilizando el método Update. Se puede realizar operaciones en un DataTable: añadir registros, modificar sus datos, eliminar los registros. Para confirmar los registros, se utiliza los métodos AcceptChanges (actualizar) o RejectChanges (deshacer los cambios). Las filas de un DataTable, según su operación manejan estados: Added, Deleted, Modified y Unchanged. Ello para que éstas sean visualizadas por el DataRowVersion. El DataView es una vista de datos de una tabla, la cual puede realizar operaciones de ordenamiento y filtro, independiente de la tabla de origen. Si desea consultar mas acerca de estos temas puede consultar las siguientes paginas:
http://msdn2.microsoft.com/es-es/library/zb0sdh0b(VS.80).aspx Página que explica la estructura del DataSet de ADO.NET
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
103
UNIDAD DE APRENDIZAJE
2 SEMANA
6 OPERACIONES DE SCONECTADAS: USO DEL DATAVIEW Y EL DATATABLEREADER LOGRO DE LA UNIDAD DE APRENDIZAJE Al término de la unidad, los alumnos elaboran aplicaciones Windows .NET que accedan a un origen de datos en forma desconectada utilizando los objetos del ADO.NET para obtener una mejor performance en los procesos de consulta y actualización de una aplicación.
TEMARIO • • • • •
Creación y definición DataSet, DataTable, Constraint y DataView. Proceso de consulta y actualización de datos desconectados en un DataSet. Operaciones desconectadas utilizando el Asistente del Visual Studio. Operaciones de consultas utilizando el DataView. Manejo de un DataTableReader desde un DataSet o DataTable.
ACTIVIDADES PROPUESTAS •
Los alumnos realizan operaciones de consulta en un DatView.
•
Los alumnos realizan operaciones de consulta en un DataTableReader sobre un DataSet o DataTable.
CIBERTEC
CARRERAS PROFESIONALES
104
1.
DATAVIEW Una DataView proporciona una vista de datos dinámica en la DataTable subyacente: el contenido, el orden y la pertenencia reflejan los cambios en cuanto se producen. Este comportamiento difiere del método Select de la DataTable, que devuelve una matriz de DataRow de una tabla basada en un filtro o un orden determinados: este contenido refleja cambios en la tabla subyacente, pero la pertenencia y la ordenación siguen siendo estáticas.
1.1 CREACIÓN DE UN DATAVIEW Hay dos formas de crear una DataView. Puede utilizar el constructor DataView o puede crear una referencia a la propiedad DefaultView de la DataTable. El constructor DataView puede estar vacío o puede aceptar también DataTable como único argumento o DataTable junto con el criterio de filtro o de ordenación, y un filtro de estado de fila. Dim dv As DataView = dt.DefaultView
Al crear una DataView sin especificar criterios de ordenación o de filtro y establecer posteriormente las propiedades Sort, RowFilter o RowStateFilter hace que el índice se construya dos veces como mínimo: una vez al crear la DataView y otra vez más al modificar cualquiera de las propiedades de ordenación o filtro. En el siguiente ejemplo creamos un DataView definido por el DataTable dt, con un filtro RowFilter: cli_codigo=’C0001’; ordenamiento true, y que el estado de las filas sean Current. Dim dv1 As New DataView(dt, "cli_codigo='C0001'", True, DataViewRowState.CurrentRows)
1.2
ORDENAMIENTO DATAVIEW
Y
FILTRACIÓN
DE
DATOS
MEDIANTE
Proporciona varias formas de ordenación y filtrado en una DataTable: • Mediante la propiedad Sort puede especificar criterios simples o múltiples de ordenación de columnas e incluir parámetros ASC (ascendente) y DESC (descendente). • Mediante la propiedadApplyDefaultSort puede crear automáticamente un criterio de ordenación, en orden ascendente, basado en la columna o columnas de clave principal de la tabla. • La propiedad RowFilter puede especificar subconjuntos de filas basándose en sus valores de columna. • Si desea devolver los resultados de una consulta determinada en los datos, en lugar de proporcionar una vista dinámica de un subconjunto de los datos, para conseguir el máximo rendimiento utilice los métodos Find o FindRows de la DataView en lugar de establecer la propiedad RowFilter. La propiedad RowFilter es más idónea en una aplicación enlazada a datos donde un control enlazado muestra resultados filtrados. Los métodos Find y FindRows aprovechan el índice actual, sin necesidad de volver a generarlo. • Mediante la propiedad RowStateFilter puede especificar las versiones de fila que desea ver. La DataView administra, implícitamente, qué versión de fila exponer, dependiendo del RowState de la fila
CARRERAS PROFESIONALES
CIBERTEC
PROGRAMACIÓN ORIENTADA A OBJETOS II
105
subyacente. Por ejemplo, si el RowStateFilter está establecido como DataViewRowState.Deleted, la DataView expone la versión de fila Original de todas las filas Deleted, porque no hay ninguna versión de fila Current. En la siguiente tabla se muestran las opciones de DataViewRowState. Estado
Descripción
CurrenRows
Valor predeterminado, la versión de fila Current de las filas Unchanged, Added, Modified.
Added
Versión de todas las filas Added.
ModifiedCurrent
Versión de la fila Current de las filas Modified.
Deleted
Versión de todas las filas Deleted.
ModifiedOriginal
Versión de fila Original de las filas Modified.
OriginalRows
Versión de fila Original de filas Unchanged, Modified y Deleted.
Unchanged
Versión de fila Current de las filas Unchanged.
El siguiente ejercicio, crea una vista de la tabla artículos que muestra los registros donde su stock sea menor a 50, y que esté ordenado por su nombre en forma descendente. Dim dv As DataView = dt.DefaultView dv.RowFilter = "art_stock=@f1 AND p.FechaPedido
View more...
Comments