Ejemplo - Acceso a Datos

Anuncio
ADO.NET
Introducción
La mayoría de las aplicaciones escritas en Visual Basic y Visual C# giran en torno a la lectura y actualización de
información de bases de datos. Para permitir la integración de datos en aplicaciones distribuidas y escalables,
Visual Studio .NET es compatible con una nueva generación de tecnología de acceso a datos: ADO.NET.
El problema es comunicar un programa o aplicación con una base de datos y más que comunicar se pretende
que el programa o aplicación realice una serie de procesos u operaciones con la base de datos o mejor aun con
el conjunto de tablas que contiene una base de datos.
La primera nota a recordar es que una base de datos puede estar físicamente en el servidor y en algún fólder o
directorio del disco duro de dicha maquina. Otra cosilla que debemos recordar es que así como existen
servidores de paginas (Web Server), servidores de correo (Mail Server), servidores de ftp (ftp Server),...,
también existen servidores de bases de datos (DataBase Server), los más comunes son el SqlServer de
Microsoft, Oracle, MySql, y muchos más, estos servidores también pueden crear, administrar y procesar una
base de datos.
El modo de comunicación entre nuestra aplicación y la base de datos implica que ambos manejen un lenguaje
de programación común, es decir no se puede mandar una instrucción en C# .net, o en visual Basic .net o en
Basic o pascal...o en cualquier otro lenguaje, a la base de datos y además esperar que esta última la entienda.
Para entender esto, una razón muy sencilla es que la base de datos tendría que conocer o comprender todos
los lenguajes de programación, ahora dime, no sería más fácil que exista un lenguaje común...?, entonces para
resolver este problema de comunicación es que se usa un lenguaje común de bases de datos que tanto los
lenguajes de programación existentes como las bases de datos entienden, este lenguaje común de bases de
datos es el SQL (Structured Query Languaje) o lenguaje estructurado de consultas.
La pregunta es ahora como mandamos las instrucciones SQL a la base de datos, la respuesta es mediante los
OBJETOS ADO.NET, las cuales proporcionan acceso coherente a orígenes de datos como Microsoft SQL
Server, así como a orígenes de datos expuestos mediante OLE DB y XML.
En la actualidad ADO.NET ya es parte del .NET Framework, esto quiere decir que es, de alguna manera, parte
del sistema operativo y no más un redistribuible de 4 ó 5 MB que se necesita alojar junto al cliente o junto al
instalador de una aplicación. Esto significa que nosotros, como desarrolladores, estaremos enfocados más al
acceso a datos y a la lógica para manipular estos datos, y no tendremos porqué preocuparnos en cómo a los
clientes la librería.
La mayoría de las aplicaciones necesitan algún mecanismo de acceso a datos. Si está creando una aplicación
nueva, dispone de tres opciones excelentes para obtener acceso a los datos: ADO.NET, ADO y OLE DB. Si
necesita modificar el mecanismo de acceso a datos de una aplicación existente, debería seguir utilizando la
tecnología actual de acceso a datos de la aplicación por cuestiones de mantenimiento.
Si usted prevé que la aplicación va a tener un ciclo de vida largo, entonces debe considerar la posibilidad de
rediseñar la tecnología de acceso a datos de la aplicación y utilizar ADO.NET en aplicaciones administradas o
ADO en aplicaciones nativas. A largo plazo, el uso de las tecnologías más modernas de acceso a datos reduce
el tiempo de desarrollo, simplifica el código y proporciona un rendimiento excelente.
Acceso a datos con ADO.NET
•
ADO.NET es una tecnología de acceso a datos que se basa en los objetos ADO (Objetos de Datos ActiveX)
anteriores.
•
Es una manera nueva de acceder a los datos construida sobre ADO. ADO.NET puede coexistir con ADO.
•
También podemos decir que ADO.NET es un conjunto de clases que exponen servicios de acceso a datos
al programador de .NET.
•
ADO.NET proporciona un conjunto variado de componentes para crear aplicaciones distribuidas de uso
compartido de datos. Forma parte integral de .NET Framework, y proporciona acceso a datos relacionales,
datos XML y datos de aplicaciones.
•
ADO.NET es compatible con diversas necesidades de programación, incluida la creación de clientes de
bases de datos clientes y objetos empresariales de nivel medio utilizados por aplicaciones, herramientas,
lenguajes o exploradores de Internet.
•
ADO.NET utiliza un modelo de acceso pensado para entornos desconectados. Esto quiere decir que la
aplicación se conecta al origen de datos, hace lo que tiene que hacer, por ejemplo seleccionar registros, los
carga en memoria y se desconecta del origen de datos.
•
ADO.NET es un conjunto de clases que usted utiliza para acceder y manipular orígenes de datos como por
ejemplo, una base de datos en SQL Server o una planilla Excel.
•
ADO.NET utiliza XML como el formato para transmitir datos desde y hacia su base de datos y su aplicación
Web.
•
Hay 3 espacios de nombres que se importará en un formulario Web o formulario Windows si esta usando
ADO.NET:
o
System.Data.
o
System.Data.SqlClient.
o
System.Data.OleDb.
Espacios de nombres para datos en el .NET Framework
Entre los espacios de nombres de .NET Framework relativos a datos y XML se incluyen:
Espacio de Nombre
System.Data
System.Data.Common
System.Xml
System.Data.OleDb
System.Data.SqlClient
System.Data.SqlTypes
System.Data.OleDb
System.Data.OracleClient
Descripción
Consiste en las clases que constituyen la arquitectura ADO.NET, que es el
método primario para tener acceso a los datos de las aplicaciones administradas.
La arquitectura ADO.NET permite crear componentes que administran
eficientemente datos procedentes de múltiples orígenes. ADO.NET también
proporciona las herramientas necesarias para solicitar, actualizar y reconciliar
datos en aplicaciones distribuidas.
Contiene las clases que comparten los proveedores de datos .NET Framework.
Dichos proveedores describen una colección de clases que se utiliza para obtener
acceso a un origen de datos, como una base de datos, en el espacio
administrado.
Clases que proporcionan funcionalidad basada en estándares para procesar
código XML.
Clases que componen el proveedor de datos de .NET Framework para orígenes
de datos compatibles con OLE DB. Estas clases permiten conectarse a un origen
de datos OLE DB, ejecutar comandos en el origen y leer los resultados.
Clases que conforman el proveedor de datos de .NET Framework para SQL
Server, que permite conectarse a un origen de datos SQL Server 7.0, ejecutar
comandos y leer los resultados. El espacio de nombres System.Data.SqlClient es
similar al espacio de nombres System.Data.OleDb, pero optimizado para el
acceso a SQL Server 7.0 y versiones posteriores.
Proporciona clases para tipos de datos nativos de SQL Server. Estas clases
ofrecen una alternativa más segura y más rápida a otros tipos de datos.
Clases que componen el proveedor de datos de .NET Framework para OLE DB.
Estas clases permiten el acceso a orígenes de datos ODBC en el espacio
administrado.
Clases que componen el proveedor de datos de .NET Framework para Oracle.
Estas clases permiten el acceso a orígenes de datos Oracle en el espacio
administrado.
Componentes de ADO.NET
Existen dos componentes de ADO.NET que se pueden utilizar para obtener acceso a datos y manipularlos:
•
Proveedores de datos de .NET Framework
•
DataSet
Proveedores de datos de .NET Framework
Los proveedores de datos de .NET Framework son componentes diseñados explícitamente para la
manipulación de datos y el acceso rápido a datos de sólo lectura y sólo avance.
Objeto
Descripción
Objeto SQL
Server
Objeto para un
origen OLEDB
Connection
Establece una conexión a un origen de datos
determinado.
SqlConnection
OleDBConnection
Command
Permite tener acceso a comandos de base de datos
para devolver datos, modificar datos, ejecutar
procedimientos almacenados y enviar o recuperar
información sobre parámetros.
SqlCommand
OleDBCommand
DataReader
Proporciona un acceso rápido, hacia adelante y de
solo lectura (¿parecido al recorset no?).
SqlDataReader
OleDBDataReader
DataAdapter
Proporciona el puente entre el objeto DataSet y el
origen de datos. El DataAdapter utiliza objetos
Command para ejecutar comandos SQL en el origen
de datos tanto para cargar el DataSet con datos
como para reconciliar en el origen de datos los
cambios aplicados a los datos incluidos en el
DataSet.
SqlDataAdapter
OleDBDataAdapter
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
Transaction
CommandBuilder
ConnectionStringBuilder
Parameter
Exception
Error
ClientPermission
Descripción
Permite incluir comandos en las transacciones que se realizan en el origen de
datos. La clase base para todos los objetos Transaction es DbTransaction.
Un objeto auxiliar 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 la que puede rellenar la colección Parameters de un objeto
Command. La clase base para todos los objetos CommandBuilder es
DbCommandBuilder.
Un objeto auxiliar que proporciona un modo sencillo de crear y administrar el
contenido de las cadenas de conexión utilizadas por los objetos Connection. La
clase base para todos los objetos ConnectionStringBuilder es
DbConnectionStringBuilder.
Define los parámetros de entrada, salida y valores devueltos para los comandos y
procedimientos almacenados. La clase base para todos los objetos Parameter es
DbParameter.
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. La clase base para todos los objetos
Exception es DbException.
Expone la información relacionada con una advertencia o error devueltos por un
origen de datos.
Se proporciona para los atributos de seguridad de acceso a código de los
proveedores de datos de .NET Framework. La clase base para todos los objetos
ClientPermission es DBDataPermission.
Componente u objeto
Conjunto de datos
• DataSet
• DataTable
• DataColumm
• DataRow
• DataRelation
• Constraint
Adaptador de datos
• OleDbDataAdapter
• SqlDataAdapter
• OdbcDataAdapter
• OracleDataAdapter
• SqlDataReader
• OleDbDataReader
• OdbcDataReader
• OracleDataReader
Conexión de datos
• SqlConnection
• OleDbConnection
• OdbcConnection
• OracleConnection
Formulario Windows
Forms
Página de Formulario
Web Forms
Detalle
Los conjuntos de datos almacenan datos en una memoria caché desconectada. La
estructura de un conjunto de datos es similar a la de una base de datos relacional;
expone un modelo jerárquico de tablas, filas y columnas. Además, contiene
restricciones y relaciones definidas para el conjunto de datos.
Los adaptadores de datos son una parte integral de los proveedores administrados
por ADO.NET, que son el conjunto de objetos que se utiliza para la comunicación
entre un origen de datos y un conjunto de datos. Esto significa leer datos de una
base de datos para un conjunto de datos y, a continuación, volver escribir en la
base de datos los datos modificados del conjunto de datos. Sin embargo, un
adaptador de datos puede trasladar datos entre cualquier origen y un conjunto de
datos. Por ejemplo, podría haber un adaptador que trasladara datos entre un
servidor Microsoft Exchange y un conjunto de datos.
Para trasladar datos entre un almacén de datos y una aplicación, en primer lugar
deberá tener una conexión con el almacén de datos.
Windows Forms es la nueva plataforma de desarrollo de aplicaciones para Microsoft
Windows, basada en .NET Framework. Este marco de trabajo proporciona un
conjunto de clases claro, orientado a objetos y ampliable, que permite desarrollar
complejas aplicaciones para Windows. Además, los formularios Windows Forms
pueden actuar como interfaz de usuario local en una solución distribuida de varios
niveles.
Las páginas de formularios Web Forms pueden usarse para crear páginas Web
programables que sirvan como interfaz de usuario de las aplicaciones Web. Este
tipo de páginas presenta la información al usuario en cualquier explorador o
dispositivo cliente e implementa lógica de aplicación mediante el código de la parte
servidor. La salida de las páginas de formularios Web Forms puede contener casi
cualquier lenguaje compatible con HTTP, incluidos HTML, XML, WML y ECMAScript
(JScript, JavaScript).
DataSet
El DataSet de ADO.NET está expresamente diseñado para el acceso a datos independientemente del origen
de datos. Como resultado, se puede utilizar con múltiples y distintos orígenes de datos, con datos XML o para
administrar datos locales de la aplicación. El DataSet contiene una colección de uno o más objetos DataTable
formados por filas y columnas de datos, así como información sobre claves principales, claves externas,
restricciones y relaciones relativas a los datos incluidos en los objetos DataTable.
•
Un objeto DataSet representa un esquema (o una base de datos entera o un subconjunto de una). Puede
contener las tablas y las relaciones entre esas tablas.
o
Un objeto DataTable representa una sola tabla en la base de datos. Tiene un nombre, filas, y columnas.
-
Un objeto DataView "se sienta sobre" un DataTable y ordena los datos (como una cláusula "order
by" de SQL) y, si se activa un filtro, filtra los registros (como una cláusula "where" del SQL). Para
facilitar estas operaciones se usa un índice en memoria. Todas las DataTables tienen un filtro por
defecto, mientras que pueden ser definidos cualquier número de DataViews adicionales, reduciendo
la interacción con la base de datos subyacente y mejorando así el desempeño.
-
Un DataColumn representa una columna de la tabla, incluyendo su nombre y tipo.
-
Un objeto DataRow representa una sola fila en la tabla, y permite leer y actualizar los valores en
esa fila, así como la recuperación de cualquier fila que esté relacionada con ella a través de una
relación de clave primaria - clave extranjera.
-
Un DataRowView representa una sola fila de un DataView, la diferencia entre un DataRow y el
DataRowView es importante cuando se está interactuando sobre un resultset.
o
Un DataRelation es una relación entre las tablas, tales como una relación de clave primaria - clave
ajena. Esto es útil para permitir la funcionalidad del DataRow de recuperar filas relacionadas.
o
Un Constraint describe una propiedad de la base de datos que se debe cumplir, como que los valores
en una columna de clave primaria deben ser únicos. A medida que los datos son modificados cualquier
violación que se presente causará excepciones.
Un DataSet es llenado desde una base de datos por un DataAdapter cuyas propiedades Connection y
Command que han sido iniciados. Sin embargo, un DataSet puede guardar su contenido a XML (opcionalmente
con un esquema XSD), o llenarse a sí mismo desde un XML, haciendo esto excepcionalmente útil para los
servicios Web, computación distribuida, y aplicaciones ocasionalmente conectadas.
En el diagrama siguiente se ilustra la relación entre un proveedor de datos de .NET Framework y un DataSet.
Arquitectura de ADO.NET
Imports System.Data.OleDb
Imports System.Data.SqlClient
Imports System.Data
Public Class SQLServer2005
Private conexion As SqlConnection
Private cadenaConexion As String
' Cadena de conexión con autentificación de SQL Server
Public Function abrirConexion(ByVal fuenteDatos As String, _
ByVal catalogo As String, _
ByVal usuario As String, _
ByVal clave As String) As SqlConnection
cadenaConexion = "data source=" & fuenteDatos & ";" & _
"inicial catalog=" & catalogo & ";" & _
"user id=" & usuario & ";" & _
"password=" & clave
Try
'Abrimos la conexión
conexion = New Data.SqlClient.SqlConnection(cadenaConexion)
conexion.Open()
Catch ex As Exception
MessageBox.Show("Error al abrir la conexión:" & vbCrLf & ex.Message)
End Try
Return conexion
End Function
' Cadena de conexión con autentificación de Windows
Public Function abrirConexion(ByVal servidor As String, _
ByVal baseDatos As String, _
ByVal integratedSecurity As String) As SqlConnection
cadenaConexion = "Server=" & servidor & ";" & _
"DataBase=" & baseDatos & ";" & _
"integrated security=" & integratedSecurity & ";"
Try
'Abrimos la conexión
conexion = New Data.SqlClient.SqlConnection(cadenaConexion)
conexion.Open()
Catch ex As Exception
MessageBox.Show("Error al abrir la conexión:" & vbCrLf & ex.Message)
End Try
Return conexion
End Function
Public Sub cerrarConexion()
Try
'Cerramos la conexión
conexion.Close()
Catch ex As Exception
MessageBox.Show("Error al cerrar la conexión:" & vbCrLf & ex.Message)
Exit Sub
End Try
End Sub
End Class
Imports System.Data.OleDb
Imports System.Data.SqlClient
Imports System.Data
Public Class Alumno
Private
Private
Private
Private
Private
Private
Private
Private
Private
conector As New SQLServer2005
conexion As SqlConnection = Nothing
comandoSQL As SqlCommand = Nothing
parametroSQL As SqlParameter
da As SqlDataAdapter
ds As DataSet
dt As DataTable
dr As DataRow
consultaSQL As String
Private servidor As String = "XQPCUEVA\SQLEXPRESS2005"
Private baseDatos As String = "EjemploVB"
Private seguridadIntegrada As String = "SSPI"
' Consultar alumnos por CI
Public Function consultarAlumno(ByVal cedula As Integer) As DataSet
' Se abre la conexion
' Si la conexión es local se puede cambiar el nombre del servidor por (local)
' conexion = helper.abrirConexion("(local)\SQLEXPRESS", "EjemploVB", "YES")
conexion = conector.abrirConexion(servidor, baseDatos, seguridadIntegrada)
' (Nombre del Stored Procedure, Conexion)
comandoSQL = New SqlCommand("consultarAlumno", conexion)
' Tipo de Comando = Stored Procedure
comandoSQL.CommandType = Data.CommandType.StoredProcedure
' Instancia del paramentro
parametroSQL = New SqlParameter("@cedula", cedula)
' Pase del parametro
comandoSQL.Parameters.Add(parametroSQL)
' Ejecución del Stored Procedure
comandoSQL.ExecuteNonQuery()
da = New SqlDataAdapter(comandoSQL)
'da = New SqlDataAdapter
'da.SelectCommand = comandoSQL
'Dim comdBuilder As New SqlCommandBuilder(da)
'Añadiríamos esta línea si la tabla tiene clave principal
'autoincremental para poder actualizar posteriormente
da.MissingSchemaAction = MissingSchemaAction.AddWithKey '(Añadir con clave)
Try
ds = New DataSet
'Cargamos el DataSet
da.Fill(ds, "Alumno")
Catch ex As Exception
MessageBox.Show("Error al cargar el DataSet:" & vbCrLf & ex.Message)
Finally
If conexion IsNot Nothing AndAlso conexion.State <> ConnectionState.Closed Then
' Cerrar conexion
conexion.Close()
End If
End Try
Return ds
End Function
' Consultar cantidad de alumnos por CI
Public Function cantidadAlumnos() As Integer
Dim cantidad As Integer
' Se abre la conexion
conexion = conector.abrirConexion(servidor, baseDatos, seguridadIntegrada)
' (Nombre Stored Procedure, Conexion)
comandoSQL = New SqlCommand("cantidadAlumnos", conexion)
' Tipo de Comando = Stored Procedure
comandoSQL.CommandType = Data.CommandType.StoredProcedure
' Ejecución del Stored Procedure
cantidad = comandoSQL.ExecuteScalar()
If conexion IsNot Nothing AndAlso conexion.State <> ConnectionState.Closed Then
' Cerrar conexion
conexion.Close()
End If
Return cantidad
End Function
Public Sub agregarAlumno(ByVal cedula As Integer, _
ByVal nombre As String, _
ByVal edad As Integer)
conexion = conector.abrirConexion(servidor, baseDatos, seguridadIntegrada)
' (Nombre Stored Procedure, Conexion)
comandoSQL = New SqlCommand("agregarAlumno", conexion)
' Tipo de Comando = Stored Procedure
comandoSQL.CommandType = Data.CommandType.StoredProcedure
' Otra forma de pasar parametro sin instanciar el objeto SqlParameter
comandoSQL.Parameters.Add("@cedula", SqlDbType.Int)
comandoSQL.Parameters("@cedula").Value = cedula
comandoSQL.Parameters.Add("@nombre", SqlDbType.NChar)
comandoSQL.Parameters("@nombre").Value = nombre
comandoSQL.Parameters.Add("@edad", SqlDbType.Int)
comandoSQL.Parameters("@edad").Value = edad
' Ejecución del Stored Procedure
comandoSQL.ExecuteNonQuery()
conexion.Close()
End Sub
End Class
Imports System.Data
Public Class frmIUGT
Private consultas As New Alumno
Private ds As DataSet
Private Sub BtnCargarGrid_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles BtnCargarGrid.Click
ds = consultas.listarAlumnos()
dgvPrueba.DataSource = ds.Tables("Alumno")
End Sub
Private Sub btnConsultarCedula_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnConsultarCedula.Click
If IsNumeric(Me.txtCI.Text) Then
ds = consultas.consultarAlumno(Me.txtCI.Text)
dgvPrueba.DataSource = ds.Tables("Alumno")
Else
MessageBox.Show("Ingrese un valor de CI válido" & vbCrLf)
End If
End Sub
Private Sub btnCantidad_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnCantidad.Click
Dim cantidad As Integer
cantidad = consultas.cantidadAlumnos
Me.lblCantidadAlumnos.Text = "La cantidad de alumno es: " & cantidad.ToString
End Sub
Private Sub btnAgregar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btnAgregar.Click
'consultas.agregarAlumno(Me.txtCI.Text, Me.txtNombre.Text, Me.txtEdad.Text)
consultas.insertarAlumno(Integer.Parse(Me.txtCI.Text), Me.txtNombre.Text,
Integer.Parse(Me.txtEdad.Text))
End Sub
Public Sub New()
' Llamada necesaria para el Diseñador de Windows Forms.
InitializeComponent()
' Agregue cualquier inicialización después de la llamada a InitializeComponent().
ds = consultas.listarAlumnos()
cmbEjemplo.DataSource = ds.Tables("Alumno")
cmbEjemplo.DisplayMember = "Nombre"
cmbEjemplo.ValueMember = "CI"
cmbEjemplo.DropDownStyle = ComboBoxStyle.DropDownList
End Sub
End Class
Descargar