1. SqlDataAdapter
SqlDataAdapter es una parte de la ADO.NET Data Provider y reside en el espacio de
nombres System.Data.SqlClient. SqlDataAdapter proporciona la comunicación entre el
conjunto de datos y la base de datos SQL. Podemos utilizar el objeto SqlDataAdapter en
combinación con el objeto DataSet.
SqlDataAdapter (Clase)
Representa un conjunto de comandos de datos y una conexión de base de datos que se
utilizan para rellenar un DataSet y actualizar una base de datos de SQL Server. Esta
clase no se puede heredar.
Espacio de nombres: System.Data.SqlClient
Ensamblado: System.Data (en system.data.dll)
Sintaxis
C#
'Declaration
Public NotInheritable Class SqlDataAdapter
Inherits DbDataAdapter
Implements IDbDataAdapter, IDataAdapter, ICloneable
'Usage
Dim instance As SqlDataAdapter
SqlDataAdapter, se utiliza como un puente entre DataSet y SQL Server para recuperar y
guardar datos. SqlDataAdapter proporciona este puente mediante la asignación de Fill,
que cambia los datos en DataSet para que coincidan con los datos del origen de datos; y
Update, que cambia los datos en el origen de datos para que coincidan con los datos en
DataSet utilizando las instrucciones de Transact-SQL en el origen de datos adecuado.
Cuando SqlDataAdapter rellene un objeto DataSet, creará las tablas y columnas
necesarias para los datos devueltos si todavía no existen. Sin embargo, la información de
clave principal no se incluirá en el esquema creado implícitamente a menos que la
propiedad MissingSchemaAction se establezca en AddWithKey. También se puede hacer
que SqlDataAdapter cree el esquema de DataSet, incluida la información de clave
principal, antes de rellenarlo de datos mediante el método FillSchema. Para obtener más
información, vea Agregar restricciones existentes a DataSet.
SqlDataAdapter se utiliza junto con SqlConnection y SqlCommand para aumentar el
rendimiento en la conexión con una base de datos de SQL Server.
2. SqlDataAdapter contiene también las propiedades SelectCommand, InsertCommand,
DeleteCommand, UpdateCommand y TableMappings para facilitar la carga y la
actualización de los datos.
Cuando se crea una instancia de SqlDataAdapter, las propiedades de lectura y escritura
se establecen en sus valores iniciales. Para obtener una lista de esos valores, vea el
constructor SqlDataAdapter.
Ejemplo
En el ejemplo siguiente se utilizan SqlCommand, SqlDataAdapter y SqlConnection para
seleccionar registros de una base de datos, y se rellena DataSet con las filas
seleccionadas. A continuación, se devuelve el DataSet rellenado. Para ello, al método se
le pasan un DataSet inicializado, una cadena de conexión y una cadena de consulta que
es una instrucción SELECT de Transact-SQL.
C#
Public Function SelectRows( _
ByVal dataSet As DataSet, ByVal connectionString As String, _
ByVal queryString As String) As DataSet
Using connection As New SqlConnection(connectionString)
Dim adapter As New SqlDataAdapter()
adapter.SelectCommand = New SqlCommand( _
queryString, connection)
adapter.Fill(dataSet)
Return dataSet
End Using
End Function
SqlDataAdapter (Miembros)
Representa un conjunto de comandos de datos y una conexión de base de datos que se
utilizan para rellenar un DataSet y actualizar una base de datos de SQL Server. Esta
clase no se puede heredar.
Las siguientes tablas recogen los miembros expuestos por el tipo SqlDataAdapter .
Constructores públicos
Nombre Descripción
SqlDataAdapter Sobrecargado. Inicializa una nueva instancia de la clase
SqlDataAdapter.
3. Propiedades públicas
Nombre Descripción
AcceptChangesDuringFill Obtiene o establece un valor que indica si se llama
al método AcceptChanges en un objeto DataRow
después de agregarlo a DataTable durante
cualquiera de las operaciones Fill.(Se hereda de
DataAdapter).
AcceptChangesDuringUpdate Obtiene o establece si se llama a AcceptChanges
durante una operación Update.(Se hereda de
DataAdapter).
Container Obtiene IContainer que contiene Component.(Se
hereda de Component).
ContinueUpdateOnError Obtiene o establece un valor que especifica si debe
generarse una excepción cuando se produce un
error durante una actualización de fila.(Se hereda
de DataAdapter).
DeleteCommand Obtiene o establece un procedimiento almacenado
o una instrucción de Transact-SQL para eliminar
registros de un conjunto de datos.
FillLoadOption Obtiene o establece el valor de LoadOption que
determina cómo rellena el adaptador el objeto
DataTable a partir de DbDataReader.(Se hereda de
DataAdapter).
InsertCommand Obtiene o establece un procedimiento almacenado
o una instrucción de Transact-SQL para insertar
nuevos registros en el origen de datos.
MissingMappingAction Determina la acción que hay que llevar a cabo si
los datos entrantes no tienen una tabla o una
4. columna coincidente.(Se hereda de DataAdapter).
MissingSchemaAction Determina la acción que hay que llevar a cabo
cuando el esquema DataSet existente no coincide
con los datos entrantes.(Se hereda de
DataAdapter).
ReturnProviderSpecificTypes Obtiene o establece si el método Fill debe devolver
valores específicos del proveedor o valores
comunes compatibles con CLS.(Se hereda de
DataAdapter).
SelectCommand Obtiene o establece un procedimiento almacenado
o una instrucción de Transact-SQL para seleccionar
registros en el origen de datos.
Site Obtiene o establece ISite de Component.(Se
hereda de Component).
TableMappings Obtiene una colección que proporciona la
asignación principal entre una tabla de origen y
DataTable.(Se hereda de DataAdapter).
UpdateBatchSize Obtiene o establece el número de filas procesadas
en cada acción de ida y vuelta al servidor.
UpdateCommand Obtiene o establece un procedimiento almacenado
o una instrucción de Transact-SQL para actualizar
los registros del origen de datos.
Propiedades protegidas
Nombre Descripción
5. CanRaiseEvents Obtiene un valor que indica si el componente puede
provocar un evento.(Se hereda de Component).
DesignMode Obtiene un valor que indica si Component está
actualmente en modo de diseño.(Se hereda de
Component).
Events Obtiene la lista de controladores de eventos asociados a
Component.(Se hereda de Component).
FillCommandBehavior Obtiene o establece el comportamiento del comando
utilizado para rellenar el adaptador de datos.(Se hereda de
DbDataAdapter).
Métodos públicos
Nombre Descripción
CreateObjRef Crea un objeto que contiene toda la
información relevante necesaria para
generar un proxy utilizado para
comunicarse con un objeto remoto.
(Se hereda de MarshalByRefObject).
Dispose Sobrecargado. Libera los recursos
utilizados por el objeto Component.
(Se hereda de Component).
Equals Sobrecargado. Determina si dos
instancias de Object son iguales. (Se
hereda de Object).
Fill Sobrecargado. Rellena un objeto
DataSet o un objeto DataTable. (Se
hereda de DbDataAdapter).
6. FillSchema Sobrecargado. Agrega DataTable a
DataSet y configura el esquema para
hacerlo coincidir con el del origen de
datos. (Se hereda de
DbDataAdapter).
GetFillParameters Obtiene los parámetros establecidos
por el usuario al ejecutar una
instrucción SELECT de SQL. (Se
hereda de DbDataAdapter).
GetHashCode Sirve como función hash para un tipo
concreto. GetHashCode es apropiado
para su utilización en algoritmos de
hash y en estructuras de datos como
las tablas hash. (Se hereda de
Object).
GetLifetimeService Recupera el objeto de servicio de
duración actual que controla la
directiva de duración de esta
instancia. (Se hereda de
MarshalByRefObject).
GetType Obtiene el objeto Type de la instancia
actual. (Se hereda de Object).
InitializeLifetimeService Obtiene un objeto de servicio de
duración para controlar la directiva de
duración de esta instancia. (Se
hereda de MarshalByRefObject).
ReferenceEquals Determina si las instancias de Object
especificadas son la misma instancia.
(Se hereda de Object).
ResetFillLoadOption Restablece FillLoadOption a su
estado predeterminado y hace que
Fill tenga en cuenta
7. AcceptChangesDuringFill. (Se hereda
de DataAdapter).
ShouldSerializeAcceptChangesDuringFill Determina si se debe conservar la
propiedad AcceptChangesDuringFill.
(Se hereda de DataAdapter).
ShouldSerializeFillLoadOption Determina si se debe conservar la
propiedad FillLoadOption. (Se hereda
de DataAdapter).
ToString Devuelve un objeto String que
contiene el nombre del objeto
Component, en caso de que exista.
Este método no debe reemplazarse.
(Se hereda de Component).
Update Sobrecargado. Llama a las
instrucciones INSERT, UPDATE o
DELETE respectivas para cada fila
insertada, actualizada o eliminada en
DataSet. (Se hereda de
DbDataAdapter).
Métodos protegidos
Nombre Descripción
AddToBatch Agrega una interfaz IDbCommand al lote actual.
(Se hereda de DbDataAdapter).
ClearBatch Quita todos los objetos IDbCommand del lote. (Se
hereda de DbDataAdapter).
CloneInternals Crea una copia de esta instancia de DataAdapter.
8. (Se hereda de DataAdapter).
CreateRowUpdatedEvent Inicializa una nueva instancia de la clase
RowUpdatedEventArgs. (Se hereda de
DbDataAdapter).
CreateRowUpdatingEvent Inicializa una nueva instancia de la clase
RowUpdatingEventArgs. (Se hereda de
DbDataAdapter).
CreateTableMappings Crea una nueva colección
DataTableMappingCollection. (Se hereda de
DataAdapter).
Dispose Sobrecargado. Libera los recursos utilizados por
el objeto Component. (Se hereda de Component).
ExecuteBatch Ejecuta el lote actual. (Se hereda de
DbDataAdapter).
Fill Sobrecargado. Rellena un objeto DataSet o un
objeto DataTable. (Se hereda de DbDataAdapter).
FillSchema Sobrecargado. Agrega DataTable a DataSet y
configura el esquema para hacerlo coincidir con el
del origen de datos. (Se hereda de
DbDataAdapter).
Finalize Libera recursos no administrados y realiza otras
operaciones de limpieza antes de que se reclame
el objeto Component durante la recolección de
elementos no utilizados. (Se hereda de
Component).
GetBatchedParameter Devuelve una interfaz IDataParameter de uno de
los comandos del lote actual. (Se hereda de
9. DbDataAdapter).
GetService Devuelve un objeto que representa el servicio
suministrado por Component o por Container. (Se
hereda de Component).
HasTableMappings Indica si se ha creado una colección
DataTableMappingCollection. (Se hereda de
DataAdapter).
InitializeBatching Inicializa el procesamiento por lotes de
DbDataAdapter. (Se hereda de DbDataAdapter).
MemberwiseClone Sobrecargado. (Se hereda de
MarshalByRefObject).
OnFillError Se invoca cuando aparece un error durante una
operación Fill. (Se hereda de DataAdapter).
OnRowUpdated Provoca el evento RowUpdated de un proveedor
de datos de .NET Framework. (Se hereda de
DbDataAdapter).
OnRowUpdating Provoca el evento RowUpdating de un proveedor
de datos de .NET Framework. (Se hereda de
DbDataAdapter).
ShouldSerializeTableMappings Determina si uno o más objetos
DataTableMapping existen y si deben
almacenarse. (Se hereda de DataAdapter).
TerminateBatching Finaliza el procesamiento por lotes para
DbDataAdapter. (Se hereda de DbDataAdapter).
Update Sobrecargado. Llama a las instrucciones INSERT,
UPDATE o DELETE respectivas para cada fila
insertada, actualizada o eliminada en DataSet.
10. (Se hereda de DbDataAdapter).
Eventos públicos
Nombre Descripción
Disposed Agrega un controlador de eventos para escuchar el evento Disposed
en el componente.(Se hereda de Component).
FillError Se devuelve cuando se produce un error durante una operación de
relleno.(Se hereda de DataAdapter).
RowUpdated Se produce durante Update después de que se ejecute un comando
en el origen de datos. Se ha realizado un intento de actualización, de
manera que se inicia el evento.
RowUpdating Se produce durante el método Update antes de que se ejecute un
comando en el origen de datos. Se ha realizado un intento de
actualización, de manera que se inicia el evento.
Implementaciones explícitas de interfaces
Nombre Descripción
System.ICloneable.Clone Para obtener una descripción
de este miembro, vea Clone.
System.Data.IDbDataAdapter.DeleteCommand Para obtener una descripción
de este miembro, vea
DeleteCommand.
11. System.Data.IDbDataAdapter.InsertCommand Para obtener una descripción
de este miembro, vea
InsertCommand.
System.Data.IDbDataAdapter.SelectCommand Para obtener una descripción
de este miembro, vea
SelectCommand.
System.Data.IDbDataAdapter.UpdateCommand Para obtener una descripción
de este miembro, vea
UpdateCommand.
SqlDataAdapter (Constructor)
Inicializa una nueva instancia de la clase SqlDataAdapter.
Lista de sobrecarga
Nombre Descripción
SqlDataAdapter () Inicializa una nueva instancia de la clase SqlDataAdapter.
Compatible con .NET Compact Framework.
SqlDataAdapter Inicializa una nueva instancia de la clase SqlDataAdapter con
(SqlCommand) el objeto SqlCommand especificado como propiedad
SelectCommand.
Compatible con .NET Compact Framework.
SqlDataAdapter (String, Inicializa una nueva instancia de la clase SqlDataAdapter con
SqlConnection) una propiedad SelectCommand y un objeto SqlConnection.
Compatible con .NET Compact Framework.
12. SqlDataAdapter (String, Inicializa una nueva instancia de la clase SqlDataAdapter con
String) una propiedad SelectCommand y una cadena de conexión.
Compatible con .NET Compact Framework.
SqlDataAdapter interactúa con el tipo DataTable. Se puede llenar un DataTable con una
tabla de la base de datos de SQL Server. Aquí vemos un ejemplo rápido. A continuación,
repasamos una mesa de revisión de los miembros de SqlDataAdapter diferentes.
En este artículo se describe SqlDataAdapter C #. Se utiliza SqlDataAdapter en un
programa de Windows Forms.
Ejemplo
Este es un ejemplo del código SqlDataAdapter. Usted tendrá que cambiar el comando
SELECT para utilizar una tabla de su base de datos personalizada. Además, es posible
que necesite un control DataGridView en su programa de Windows Forms. Tenga en
cuenta que SqlDataAdapter no requiere el control DataGridView. Sin embargo,
DataGridViews son un uso muy común.
Programa que utiliza el tipo SqlDataAdapter [C #]
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
espacio de nombres WindowsFormsApplication1
{
public partial class Form1: Form
{
public Form1 ()
{
InitializeComponent ();
FillData ();
}
13. FillData vacío ()
{
//1
/ / Abrir la conexión
utilizando (SqlConnection c = new SqlConnection (
Properties.Settings.Default.DataConnectionString))
{
c.Open ();
//2
/ / Crear nuevo DataAdapter
utilizando (a = new SqlDataAdapter SqlDataAdapter ("SELECT *
FROM EmployeeIDs", c))
{
//3
/ / Se utiliza DataAdapter para rellenar DataTable
DataTable t = new DataTable ();
a.Fill (t);
//4
/ / Procesar los datos en la pantalla
/ / DataGridView1.DataSource = t / / <- A partir de su diseñador
}
}
}
}
}
Parte 1. Esto crea una instancia de SqlConnection nuevo. Tenga en cuenta que debe
incluir el espacio de nombres System.Data.SqlClient en su programa. La directiva usando
es en la parte superior del programa.
14. Parte 2. Después de llamar a Open () en la conexión SqlConnection, se utiliza otro
bloque con los SqlDataAdapters. Los estados que utilizan son ideales para disponer de
los recursos, por lo que sus programas sean más eficientes y confiables.
Parte 3. Aquí tenemos una instancia nueva y rellenar un DataTable. Tenga en cuenta
que el método de relleno en DataTable llenará las filas internas y columnas de la
DataTable para que coincidan con el resultado de SQL.
Parte 4. Esta parte está comentada, ya que no se compilará a menos que tenga un
control DataGridView. Vemos que el origen de datos que se le asigne a la DataTable. El
resultado será un DataGridView lleno de datos de SQL Server.
Propiedades
Aquí están mis notas cuando la investigación de SqlDataAdapter en mi trabajo. Tenga en
cuenta que Dispose y Finalize no son realmente útiles con la instrucción using. Se
incluyen para la integridad.
Llena. De relleno es el método más importante en los objetos DataAdapter. Se ejecuta la
consulta y llena el objeto DataAdapter con los resultados.
Deseche, Finalizar. Estos métodos están disponibles porque SqlDataAdapter utiliza
recursos importantes del sistema y que debe administrarse con el uso. Cuando se utiliza
el uso, no es necesario llamar a estos métodos.
OnFillError. Este es un evento que le permite escuchar cuando se produjo un error al
llenar el DataTable. Por favor, vea el método de relleno.
OnRowUpdated, OnRowUpdating. Estos son eventos que le permiten recibir los
mensajes cuando se producen las acciones especificadas.
GetFillParameters. Esto le permite obtener los parámetros que se utilizan en una
instrucción SELECT. Puede ser útil cuando se necesita para comprobar qué columnas se
realiza la consulta en su base de datos.
Un ejemplo para usar transacciones con un DataAdapter
Lo mejor es que veamos qué tenemos que hacer para que todo esto que te he comentado
funcione correctamente.
En el siguiente ejemplo sólo veremos la parte en la que se utiliza un objeto
CommandBuilder.
En estos ejemplos voy a usar una base de datos de SQL Server 2005 Express, que es la
misma que ya usé en el ejemplo del artículo anterior.
15. Nota:
Por ahora solo te muestro el código de Visual Basic, en otra ocasión actualizaré
el código para incluir el de C#.
Aquí solamente veremos la parte de la actualización, es decir, lo que debemos ejecutar
para actualizar los datos una vez modificados, por tanto este código que te muestro es
cuando ya has modificado los datos... eso no te lo muestro porque en realidad no cambia
con respecto a lo que ya te he explicado en otras ocasiones, desde el índice de la sección
de ADO.NET tienes varios ejemplos de cómo acceder a los datos usando un adaptador.
Nota:
Hay que tener en cuenta que este código solo es para mostrar los pasos a dar,
ya que antes se han tenido que leer los datos, asignarlos al DataSet o
DataTable, y modificarlos de alguna forma que aquí no se muestra (esto lo aclaro
para que después no andes preguntando o diciendo que esto no cambia nada en
la base de datos o que este ejemplo no funciona, y te puedo asegurar que sí
funciona, que yo lo he probado insertando y modificando datos...)
Paso 1. Creamos el adaptador (y la conexión y el objeto Connection)
El comando SELECT es necesario para que el CommandBuilder sepa cómo debe crear
los comandos.
' La cadena de conexión
Dim csb As New SqlConnectionStringBuilder
With csb
' El servidor al que nos conectamos
.DataSource = "(local)SQLEXPRESS"
' La base de datos que vamos a usar
.InitialCatalog = "prueba"
' Usamos la seguridad integrada
.IntegratedSecurity = True
End With
' Creamos la conexión
' la ponemos dentro de Using para asegurarnos de que se cierre si hay errores
16. Using con As New SqlConnection(csb.ConnectionString)
Dim dt As New DataTable
' Creamos el adaptador usando el objeto Connection
Dim da As New SqlDataAdapter("SELECT * FROM Table1", con)
da.MissingSchemaAction = MissingSchemaAction.AddWithKey
Paso 2. Creamos los comandos y los asignamos al adaptador, si no lo hacemos de esta
forma, al intentar acceder a los comandos desde el objeto del DataAdapter...
obtendremos un error indicando que no están creados (son nulos).
' Creamos los comandos con el CommandBuilder
Dim cb As New SqlCommandBuilder(da)
' pero para asignarle el objeto Transaction debemos
' obtenerlos por medio de los métodos Get...Command
' ya que si intentamos acceder directamente a esos comandos
' del adaptador nos indicará que no están asignados (son nulos)
da.InsertCommand = cb.GetInsertCommand()
da.UpdateCommand = cb.GetUpdateCommand()
da.DeleteCommand = cb.GetDeleteCommand()
Paso 3. Abrimos la conexión y creamos el objeto Transaction llamando al método
BeginTransaction, y asignamos ese objeto a cada uno de los comandos del adaptador,
salvo al comando de selección.
' Abrimos la conexión
con.Open()
' Creamos el objeto Transaction
Dim tran As SqlTransaction = con.BeginTransaction
17. ' Asignamos el objeto Transaction a los comandos
da.InsertCommand.Transaction = tran
da.UpdateCommand.Transaction = tran
da.DeleteCommand.Transaction = tran
Paso 4. Dentro de un bloque Try/Catch (para detectar los errores) es cuando
actualizamos los datos llamando al método Update del adaptador. Es importante que la
conexión siga abierta, ya que el objeto de la variable tran depende de esa conexión, pero
el adaptador no depende directamente de la conexión abierta en la variable con, ya que el
adaptador gestiona por su cuenta las conexiones y si ve que está cerrada, la abrirá, pero
esa apertura es independiente del objeto que hemos usado para indicarle cuál es la
conexión que debe usar... ¡un lío! pero es así...
Hay que tener en cuenta que la "aceptación" de los cambios del DataTable (o DataSet)
se hace de forma independiente de la llamada a los métodos Commit (o Rollback) del
objeto Transaction. En el caso de que todo vaya bien, el propio método Update del
adaptador se encarga de decirle a la tabla que acepte los cambios, por tanto no es
necesario llamar de forma explícita al método AcceptChanges, ya que esa es la forma
"predeterminada" de actuar (lee el comentario del código si quieres saber algo más de
esto... y, por supuesto, después te lees la documentación para informarte mejor, que con
un par de líneas de comentarios no lo vas a aprender todo, jejeje).
Cuando se cancela la actualización (en el bloque Catch del ejemplo), se hace una llamada
al método Rollback del objeto Transaction, y también podrías llamar al método
RejectChanges de la tabla, pero esto supondría perder TODAS las modificaciones que
hayas hecho en los datos que están en memoria. Y debido a que esos datos están en
memoria, puedes volver a actualizarlos posteriormente si así lo consideras necesario.
Nuevamente te invito a que leas los comentarios del código para que veas qué debes
hacer.
Try
' Para probar con un error
If chkProducirError.Checked Then
Throw New Exception("Candemore")
End If
' Actualizamos los datos de la tabla
da.Update(dt)
18. ' Si llega aquí es que todo fue bien,
' por tanto, llamamos al método Commit
tran.Commit()
' Esto no es necesario si dejamos el valor predeterminado
' de la propiedad AcceptChangesDuringUpdate del adaptador
dt.AcceptChanges()
txtInfo.Text = "Se han actualizado los datos"
Catch ex As Exception
' Si hay error, desahacemos lo que se haya hecho
tran.Rollback()
' Desechar los cambios del DataTable
' si así lo estimamos oportuno,
' pero esto obligará a volver a añadir, modificar o eliminar
' nuevamente los datos.
' Por tanto, solo debemos hacerlo si no intentaremos nuevamente
' la actualización de los datos.
' Yo preguntaría al usuario antes de hacerlo...
'dt.RejectChanges()
txtInfo.Text = "ERROR: " & vbCrLf & ex.Message
End Try
19. Paso 5. Finalmente cerramos la conexión, aunque no es necesario hacerlo de forma
explícita ya que al incluir el objeto Connection dentro de un bloque Using, se cerrará
automáticamente.
' Cerramos la conexión,
' aunque no es necesario ya que al finalizar
' el using se cerrará
con.Close()
End Using