ADO desconectado - entornosgraficos

Anuncio
1
ADO .NET Desconectado.
ADO.NET proporciona un conjunto de componentes para crear aplicaciones distribuidas de uso
compartido de datos. Dichos componentes están diseñados para separar el acceso a los datos de la
manipulación de los mismos.
Como ya sabemos, estos componentes son: DataSet y el proveedor de datos de .NET Framework, que
es un conjunto de componentes entre los que se incluyen los objetos: conexión (Connection), de
órdenes (Command), lector de datos (DataReader) y el adaptador de datos (DataAdapter).
Un formulario Windows, para acceder a los datos de un origen de datos lo puede realizar de dos modos:
- Conectado. Interactuando directamente con la base de datos.
- Desconectado. Utilizando un adaptador de datos para leer la información de la base de datos y
almacenarla en el conjunto de datos (DataSet). Posteriormente, cuando se requiera escribir en el
origen de datos, se volverá a utilizar el adaptador, que tomará los datos del conjunto de datos
(DataSet).
ADO.NET y Windows Forms proporcionan otros componentes que se pueden utilizar para mostrar los
datos. Incluyen controles como DataView, DataGrid, que pueden ser enlazados a datos, y propiedades
de enlace a datos en la mayoría de controles estándares de Windows, como los controles TextBox,
Label, ComboBox y ListBox.
Vista de datos.
La clase DataView permite representar los datos de la clase DataTable (de una tabla), creando
múltiples vistas de los mismos, puesto que permite editar, ordenar y filtrar, buscar y navegar por un
conjunto de datos determinado.
Adaptador de datos. Clases DataAdapter y TableAdapter.
Un adaptador de datos es un conjunto de objetos utilizado para intercambiar datos entre el origen de
datos y el conjunto de datos (DataSet).
Utiliza los objetos Connection, Command y DataReader implícitamente para poblar un objeto
DataSet y para actualizar la fuente de datos central con los cambios efectuados en el DataSet.
Existe una clase DataAdapter para cada proveedor de datos: OleDbDataAdapter, SqlDataAdapter, etc.
Generalmente, cada adaptador de datos, intercambia datos entre una sola tabla del origen de datos y un
solo objeto DataTable del conjunto de datos. Lo normal es utilizar tantos adaptadores como tablas tenga
el conjunto de datos. De esta forma, cada tabla del conjunto de datos tendrá su correspondiente tabla en
el origen de datos.
A partir de la versión Visual Studio 2005 aparecen los objetos TableAdapter. Se pueden pensar en un
TableAdapter como un DataAdapter que lleva integrado un objeto de conexión y la capacidad de
contener varias consultas.
En resumen. El DataAdapter conecta el DataSet con el origen de datos. Esta conexión la establece a
través de los comandos (objetos Command):
- De Selección, para obtener datos de la base de datos.
SELECT * FROM Tabla
- De Acción, para actualizar datos en la base de datos
Inserción
INSER INTO .....
Eliminación
DELETE ...
Actualización UPDATE .....
2
Para poder realizar estas operaciones de conexión con el origen de datos, DataAdapter dispone de 4
propiedades a las que les asigna cada uno de estos 4 comandos:
SelectCommand = Comando de Selección
InsertCommand = Comando de Inserción
DeleteCommand = Comando de Eliminación
UpdateCommand = Comando de Actualización
'Crea un DataAdapter
Dim da As OleDbDataAdapter
da = New OleDbDataAdapter
'lo conecta
Dim Cmd As New OleDbCommand(“Select * From Tabla”, Cn)
da.SelectCommand = Cmd
El DataAdapter no sólo conecta el origen de datos (BD) con el conjunto de datos (DataSet) si no que
permite cargar o llenar el DataSet con los datos correspondientes desde el origen de datos. Para ello
dispone del método Fill, que ejecuta el comando de selección y carga los datos en el DataSet.
Nº Reg Afectados = da.Fill (ds, “AliasTabla”)
El método Fill crea en el DataSet una tabla con el nombre asignado en su 2º argumento
Se suele utilizar un DataAdapter por cada tabla del conjunto de datos (DataSet)
Para actualizar la BD con la información del DataSet, DataAdapter dispone del método Update.
Cuando se ejecuta este método, DataAdapter revisa todas las filas de la tabla del DataSet, comprobando
si cada una de ellas ha sido modificada, añadida o eliminada y ejecuta el comando de acción
correspondiente para modificar, añadir o eliminar esa fila del origen de datos.
Nº de filas Afectadas = da.Update
Resumen de los miembros.
Propiedades:
SelectCommand. Objeto de la clase Command que se va a utilizar para ejecutar una sentencia Select
de SQL.
InsertCommand. Objeto de la clase Command, que se va a utilizar para realizar una inserción de
datos.
UpdateCommand. Objeto de la clase Command que se va a utilizar para realizar una modificación de
los datos.
DeleteCommand. Objeto de la clase Command que se va a utilizar para realizar una eliminación de
datos.
Métodos:
Fill. Agrega o refresca filas en un DataSet con los datos procedentes de un DataAdapter. Devuelve un
Integer con el nº de filas afectadas.
FillSchema. Agrega una DataTable al DataSet con la estructura de la tabla con sus claves, etc. No las
relaciones.
Update. Actualiza la fuente de datos mediante los comandos de Acción. Solo escribe las
modificaciones (filas que han variado su contenido).
3
Conjunto de datos. La Clase DataSet.
Un conjunto de datos incluye una o más tablas basadas en las tablas del origen de datos y también
puede incluir información acerca de las relaciones entre esas tablas y las restricciones para los datos que
pueda contener cada tabla.
El componente central de la arquitectura sin conexión es la clase de objetos DataSet, perteneciente al
espacio de nombres System.Data, que se puede utilizar con múltiples y distintos orígenes de datos.
Como se ha visto anteriormente, en una tabla del DataSet cada fila contiene un estado. Al cargar el
DataSet se asigna a cada fila del DataTable el estado “sin cambios”. A medida que se van realizando
operaciones con las filas, a cada fila actualizada se le asigna el valor correspondiente a la operación
realizada con ella: añadida, modificada o eliminada.
El DataSet y sus objetos disponen de un conjunto de métodos que permiten actualizar o conocer el
estado de las filas de cada una de sus tablas.
Miembros más característicos de DataSet y sus objetos.
La clase DataSet incluye:
- la colección DataTableCollection de objetos DataTable (tablas de datos)
- y la colección DataRelationCollection de objetos DataRelation (relaciones entre las tablas).
La clase DataTable incluye:
- la colección DataRowCollection de objetos DataRow (filas de la tabla)
- la colección DataColumnCollection de objetos DataColumn (campos)
- y la colección Constraint (restricciones).
La clase DataRow tiene la propiedad RowState, que permite saber si la fila cambió y de qué modo,
desde que la DataTable se cargó por primera vez. Alguno de sus valores puede ser:
- Added
- Deleted
- Modified
- Unchanged.
Propiedades de DataSet
CaseSensitive. Propiedad que indica si las comparaciones de texto dentro de las tablas distinguen entre
mayúsculas y minúsculas. Por defecto tiene el valor False.
DataSetName. Establece o devuelve mediante una cadena de texto el nombre del objeto DataSet.
HasErrors. Devuelve un valor lógico para indicar si existen errores dentro de las tablas del DataSet.
Relations. Esta propiedad devuelve una colección de objetos DataRelation, que representan todas las
relaciones existentes entre las tablas del objeto DataSet.
Tables. Devuelve una colección de objetos DataTable, que representan a cada una de las tablas
existentes dentro del objeto DataSet.
Métodos
Clear. Elimina todos los datos almacenados en el objeto DataSet, vaciando todas las tablas contenidas
en el mismo. No borra las tablas
AcceptChanges. Pone el estado de las filas a “Sin Cambios”.
Las clases DataRow y DataTable también tienen métodos AcceptChanges. Si se llama a
AcceptChanges en el nivel de DataTable, se llama al método AcceptChanges para cada
DataRow. De igual forma, si se invoca a AcceptChanges en DataSet, se llama a
AcceptChanges en cada una de las tablas de DataSet. De esta forma, se puede invocar el
método desde varios niveles. Al llamar al método AcceptChanges de DataSet, se permite
4
invocar el método en todos los objetos subordinados (por ejemplo, tablas y filas) con sólo
una llamada.
Cuando se llama a AcceptChanges en DataSet, cualquier objeto DataRow que aún se
encuentre en modo de edición finalizará correctamente sus modificaciones. La propiedad
RowState de cada DataRow también cambia; las filas Added y Modified se convierten en
Unchanged y se quitan las filas Deleted.
GetChanges. Devuelve un nuevo objeto DataSet con todas las tablas y sólo las filas que hayan tenido
cambios.
HasChanges. Devuelve true o false para indicar si se han realizado cambios al contenido del DataSet
desde que fue cargado o bien desde que se realizó la última llamada al método
AcceptChanges.
RejectChanges. Abandona todos los cambios realizados en las tablas contenidas en el objeto DataSet
desde que fue cargado el objeto o bien desde la última vez que se lanzó el método
AcceptChanges.
Merge. Toma los contenidos de un DataSet y los mezcla con los de otro DataSet, de forma que
contendrá los datos de ambos objetos DataSet.
5
Procedimientos
El procedimiento para obtener un conjunto de datos (Cargar un DataSet) a través de un DataAdapter
es el siguiente:
1. Crear la conexión, el adaptador y el conjunto de datos (DataSet).
2. Crear los comandos necesarios y asignarlos al adaptador.
3. Cargar el DataSet a través del método Fill del adaptador.
Carga de un DataSet con una sentencia SQL.
Dim da As OleDbDataAdapter
'Crea un Adaptador
da = New OleDbDataAdapter
'Crea un DataAdapter con la consulta
Dim Sql As String = "Select * from Tabla"
Dim da As New OleDbDataAdapter(Sql, Cn)
'o Crea un adaptador y le asigna un comando de consulta
da = New OleDbDataAdapter
Dim Cmd As New OleDbCommand(Sql, Cn)
da.SelectCommand = Cmd
-
Llenado de una tabla (DataTable) del DataSet a través del conector DataAdapter
El método Fill del DataAdapter crea en el DataSet una tabla con el nombre
asignado en su 2º argumento. Esa DataTable se carga con los datos del
DataAdapter.
'Crear el DataSet o vaciarlo si ya estaba creado
'Crea el DataSet
ds = New DataSet
'o Dim ds As New DataSet
'Vacia el DataSet
ds.Clear()
'LLena el DataSet con una tabla
Cn.Open()
da.Fill(ds, "AliasTabla")
Cn.Close()
'llena las primeras 100 filas de la tabla
Cn.Open()
da.Fill(ds, 0, 100, "100Autores")
Cn.Close()
-
Mostrar los datos.
Para ello se enlaza el DataSet cargado con el DataGrid
'mediante las propiedades DataSource y DataMenber
With Me. DataGrid1
.DataSource = ds
.DataMember = "AliasTabla"
End With
'mediante el método SetDataBinding
DataGrid1.SetDataBinding(ds, "AliasTabla")
6
-
Crear los comandos. Utiliza comandos parametrizados
'Crear los comandos necesarios y asignarlos al adaptador
'Comando sin parámetros
'Crea el comando de Selección
Dim Cmd As New OleDbCommand("Select * from Authors", Cn)
'asigna el comando al adaptador
da.SelectCommand = Cmd
'Utilizar comando parametrizado
'crea un Ob Command de Inserción
Dim sql As String = "Insert Into Authors (Author, [Year Born]) Values(?,?)"
Dim CmdInsercion As New OleDbCommand(sql, Cn)
'añade los parámetros a la colección
With CmdInsercion.Parameters.Add("P1", OleDbType.VarChar, 50)
'Asigna valor al parámetro al ejecutarse el comando.
'Asigna el valor de la columna referenciada en la fila actual
.SourceColumn = "Author"
End With
With CmdInsercion.Parameters.Add("P2", OleDbType.SmallInt)
.SourceColumn = "Year Born"
End With
'asigna el comando al adaptador
da.InsercionCommand = CmdInsercion
7
Ejemplo. Crear un DataSet con la tabla Authors de Biblio.mdb y mostrar los autores en un
DataGrid. Utilizando un DataAdapter
Imports System.Data.OleDb
Public Class Form1
Inherits System.Windows.Forms.Form
Public Class Form1
Inherits System.Windows.Forms.Form
...
'Declarar
Dim Cn As
Dim ds As
Dim da As
los objetos: conexion, DataSet y DataAdapter
OleDbConnection
DataSet
OleDbDataAdapter
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Crea conexión
Cn = New OleDbConnection
Cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Biblio.mdb;"
'Crea Adaptador
da = New OleDbDataAdapter
'Crear los comandos necesarios y asignarlos al adaptador
Dim Cmd As New OleDbCommand("Select * from Authors", Cn)
da.SelectCommand = Cmd
'Crea el DataSet
ds = New DataSet
Call CargarDatos()
End Sub
Private Sub CargarDatos()
'Carga y muestra los datos
'Carga el DataSet y enlace con DataGrid para mostrar los datos
'Vacia el DataSet
ds.Clear()
'Llena el DataSet con una tabla
Cn.Open()
da.Fill(ds, "Autores")
Cn.Close()
'enlaza el DataSet con el DataGrid
With Me.DGridAutores
.DataSource = ds
.DataMember = "Autores"
End With
End Sub
End Class
8
Ejercicio. Añadir nuevas filas escribiendo el usuario el nombre y año de nacimiento del autor.
Partiendo del ejemplo anterior. Añadir un botón para grabar la nueva fila y dos cajas de texto
para poder escribir el nombre y año de nacimiento del autor.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Crea conexión
Cn = New OleDbConnection
Cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Biblio.mdb;"
'Crea Adaptador
da = New OleDbDataAdapter
'Crear los comandos necesarios y asignarlos al adaptador
Dim Cmd As New OleDbCommand("Select * from Authors", Cn)
da.SelectCommand = Cmd
'¡ojo! el campo Au_Id es autonumérico, no se le asigna valor
'Utiliza comando parametrizado
'crea un Ob Command con parámetros
Dim sql As String = "Insert Into Authors (Author, [Year Born]) Values(?,?)"
Dim CmdInsercion As New OleDbCommand(sql, Cn)
'asigna el comando al adaptador
da.InsertCommand = CmdInsercion
'añade los parámetros a la colección
da.InsertCommand.Parameters.Add(New OleDbParameter("P1",
OleDbType.VarChar))
da.InsertCommand.Parameters.Add(New OleDbParameter("@P2",
OleDbType.Integer))
'Crea el DataSet
ds = New DataSet
Call CargarDatos()
End Sub
Private Sub BtoGrabar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles BtoGrabar.Click
Dim NReg As Integer 'nº de registros afectados
Try
'asigna valor a los parámetros del comando de inserción
da.InsertCommand.Parameters(0).Value = Me.TxtAutor.Text
da.InsertCommand.Parameters(1).Value = CInt(Me.TxtAño.Text)
'ejecuta el comando
Cn.Open()
NReg = da.InsertCommand.ExecuteNonQuery
Cn.Close()
Call CargarDatos()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Ejercicio de Navegación por regs.
Al ejercicio anterior añadirle: 3 Etiquetas, 3 Cajas de Texto, 4 Botones: Primero, Anterior, Siguiente
y Último
9
Navegación y edición de Registros.
Para las operaciones de navegación por la tabla es obtener del DataSet, la tabla que
necesitamos mediante su colección Tables, y a su vez, a la colección Rows de esa tabla,
pasarle el número de fila/registro al que vamos a desplazarnos. Es decir:
-
Obtener la tabla del DataSet mediante su colección Tables y
la fila actual mediante la colección Rows de esa tabla
Dim nFila As Integer ' Posición fila actual
'establecer el indicador de la fila a mostrar en la tabla
Me.nFila = 0 'primera fila, u otro valor
Me.nFila = Me.ds.Tables(0).Rows.Count – 1 'última fila
'obtener un ob DataRow con la fila actual
Dim drfila As DataRow
drfila = ds.Tables("Autores").Rows(nFila)
Para las operaciones de edición:
- Se debe utilizar los miembros del objeto tabla del DataSet.
- Una vez terminado el proceso de edición, se actualizará el almacén de datos original con
el contenido del DataSet, empleando el DataAdapter
Se puede utilizar el objeto CommandBuilder para simplificar el código.
La misión del objeto CommandBuilder es la de construir automáticamente los
comandos de consulta, inserción y eliminación, y asignárselos al DataAdapter.
'Crea CommandBuilder*****sólo es necesario para operaciones de edición
Dim ComBuil As OleDbCommandBuilder = New OleDbCommandBuilder(da)
Las operaciones de edición más habituales son:
- Añadir una nueva fila
- Modificar el valor de los campos de una fila
- Eliminar una fila
- Actualizar el origen de datos con el contenido del DataSet
Procedimientos para codificar las operaciones de edición.
Añadir una fila a una tabla de un DataSet
Siempre que se inserta o añade una nueva fila se posiciona al final de la tabla.
-
Obtener un nuevo objeto fila de la tabla, con el método NewRow.
Asignar valor a sus campos.
Añadir el objeto fila a la colección de filas de la tabla.
'crea una fila nueva en la tabla del DataSet
Dim drFila As DataRow
drFila = Me.ds.Tables("Autores").NewRow
'asigna valor a los campos de la nueva fila
drFila("Au_Id") = Me.TxtAu_Id.Text
drFila.Item("Author") = Me.TxtAuthor.Text
drFila(2) = Me.TxtAño.Text
'añade el objeto fila a la colección de filas
Me.ds.Tables(0).Rows.Add(drFila)
10
Modificar los datos de una fila.
No se debe modificar el valor de los campos clave.
-
Obtener en un objeto DataRow la fila cuyos campos se desean modificar.
Dichos valores se presentan al usuario para que los pueda modificar
Asignar nuevo valor a los campos
'obtener el objeto fila
'en la que estamos posicionados
Dim drFila As DataRow
drFila = Me.ds.Tables("Autores").Rows(Me.nFila)
'Modificar los campos
With drFila
.Item(1) = Me.TxtAuthor.Text
.Item(2) = Me.TxtAño.Text
End With
Actualizar el origen de datos con el contenido del DataSet
Se utiliza el método Update del DataAdapter
El método Update toma uno de los siguientes argumentos:
Un objeto DataTable
Un DataSet más un DataTable
Una matriz de objetos DataRow
El método Update devuelve el número de filas que han sido actualizadas con éxito.
Cuando se ejecuta Update, el DataAdapter verifica la propiedad RowState de cada fila. Si el
estado es:
Added, DataAdapter ejecuta el comando SQL especificado en la propiedad InsertCommand
Modified, se ejecuta el comando especificado en UpdateCommand
Deleted, se ejecuta el comando especificado en DeleteCommand
-
Crear los comandos parametrizados de inserción, actualización y eliminación
Asignar los comandos a las propiedades InsertCommand, UpdateCommand y
DeleteCommand del DataAdapter
Actualizar la BD mediante el método Update de DataAdapter
Recordar: Las instrucciones de consulta con parámetros definen qué parámetros de
entrada y de salida se deben crear. Para crear un parámetro, se utiliza el método
Parameters.Add o el constructor Parameter con el fin de especificar el nombre de
columna, tipo de datos y tamaño. En el caso de tipos de datos intrínsecos, como
Integer, no es necesario incluir el tamaño o puede especificar el tamaño
predeterminado.
11
'Crear los comandos con parámetros
'crea el comando Insertar
Dim SqlInsert As String = "INSERT INTO Authors (Author, [Year Born]) VALUES (?, ?)"
Dim cmdInsert As New OleDbCommand(SqlInsert, Cn)
'crea los parámetros y los añade a la coleccion
With cmdInsert
'crea el parámetro y configura sus propiedades
Dim Par As OleDbParameter = .CreateParameter
.Parameters.Add(Par)
'este es el nombre de la columna en el DataTable
'permite asignar el valor al parámetro antes de ejecutarse
.Parameters(0).SourceColumn = "Author"
'se puede utilizar el valor original de cada DataRow
.Parameters(0).SourceVersion = DataRowVersion.Original
'2º parámetro
Par = .CreateParameter
.Parameters.Add(Par)
.Parameters(1).SourceColumn = "Year Born"
End With
'crea el comando Borrar
Dim cmdDelete As New OleDbCommand("DELETE FROM Authors WHERE Au_Id = ?", Cn)
With cmdDelete.Parameters.Add("P1", OleDbType.Integer)
.SourceColumn = "Au_Id"
.SourceVersion = DataRowVersion.Current 'la que tiene por defecto
End With
'crea el comando Actualizar
Dim SqlActualizar As String
SqlActualizar = "UPDATE Authors SET Author = ?, [Year Born] = ? WHERE Au_Id=?"
Dim cmdUpdate As New OleDbCommand(SqlActualizar, Cn)
With cmdUpdate.Parameters.Add("P1", OleDbType.Char, 50)
.SourceColumn = "Author"
End With
With cmdUpdate.Parameters.Add("P2", OleDbType.SmallInt)
.SourceColumn = "Year Born"
End With
With cmdUpdate.Parameters.Add("P1", OleDbType.Integer)
.SourceColumn = "Au_Id"
.SourceVersion = DataRowVersion.Current 'la que tiene por defecto
End With
'asigna los comandos a las
With Da
.InsertCommand
.DeleteCommand
.UpdateCommand
End With
propiedades xxxCommand de DataAdapter
= cmdInsert
= cmdDelete
= cmdUpdate
'Actualiza la BD mediante el método Update de DataAdapter
'enviar las filas modificadas en DataSet a BD
Dim RegActualizados As Integer
Cn.Open()
RegActualizados = Me.Da.Update(Me.Ds, "Autores")
MessageBox.Show("Reg actualizados " & RegActualizados)
Cn.Close()
Otro modo: Utiliza el objeto CommandBuilder para creaar los comandos:
12
utiliza CommandBuilder para generar las tres propiedades Command
'Crea un ob auxiliar CommandBuilder para este DataAdapter
'Para que los nombres de campos con caracteres especiales no den error:
‘encierra el nombre de los campos entre corchetes
Dim cmdBuilder As New OleDbCommandBuilder(Me.Da)
With cmdBuilder
.QuotePrefix = "["
.QuoteSuffix = "]"
End With
'Asigna los comandos a las
With Da
.InsertCommand =
.DeleteCommand =
.UpdateCommand =
End With
propiedades xxxCommand de DataAdapter
cmdBuilder.GetInsertCommand
cmdBuilder.GetDeleteCommand
cmdBuilder.GetUpdateCommand
'Enviar las filas modificadas en DataSet a BD
Dim RegActualizados As Integer
Cn.Open()
RegActualizados = Me.Da.Update(Me.Ds, "Autores")
Cn.Close()
Descargar