Hola, DeveloperNet2005:
En primer lugar, disculpa por la demora, pero he estado un poco ocupado el fin de semana. Pero finalmente, ya tengo listo lo que necesitabas: un conjunto de rutinas para insertar en una base de datos de MSAccess los datos leídos a partir de un archivo XML. Y, tal como lo solicitaste, he implementado el caso en el que la estructura de los datos es idéntica a la de las tablas de MSAccess. Además, te adjunto el proyecto completo en el que desarrollé la solución, para que veas completamente cómo está estructurada, ya que muchas veces unos pequeños fragmentos de código no son suficientes.
Paso a detallarte el código utilizado. Empiezo con mis rutinas de ayuda. El siguiente método recibe 3 parámetros: un IDbCommand, un DataSet y un String. Ejecuta el comando (que puede utilizar el proveedor de datos OleDB o el de MSSQL, ya que heredan de IdbCommand, y tiene que ser una consulta de selección, o sea, “SELECT …”), carga los datos devueltos por la consulta en el DataTable con el nombre especificado por el String, y agrega el DataTable a la colección Tables del DataSet.
Private Sub LoadDataTable(ByVal cmd As IDbCommand, ByVal ds As DataSet, ByVal tableName As String)
Try
If TypeOf cmd Is SqlCommand Then
Dim da As New SqlDataAdapter(cmd)
da.Fill(ds, tableName)
ElseIf TypeOf cmd Is OleDbCommand Then
Dim da As New OleDbDataAdapter(cmd)
da.Fill(ds, tableName)
End If
Catch ex As Exception
' Si se lanza alguna excepción, se muestra su mensaje correspondiente
MsgBox(ex.Message)
End Try
End Sub
De manera similar, el siguiente método recibe además de los 3 parámetros ya vistos, un objeto de tipo IDbDataAdapter. Fíjate que utiliza ByRef en vez de ByVal para el IdbDataAapter, puesto que al finalizar la ejecución del método, dicho objeto debe mantener la inicialización que se ejecuta en el cuerpo del método. De esta manera, el objeto DataAdapter utilizado para cargar los datos en el DataSet es externo al método y puede ser llamado luego, como veremos más adelante.
Private Sub LoadDataTable(ByVal cmd As IDbCommand, ByVal ds As DataSet, ByVal tableName As String, ByRef da As IDbDataAdapter)
Try
If TypeOf cmd Is SqlCommand Then
da = New SqlDataAdapter(cmd)
CTye(da, SqlDataAdapter).Fill(ds, tableName)
ElseIf TypeOf cmd Is OleDbCommand Then
da = New OleDbDataAdapter(cmd)
CType(da, OleDbDataAdapter).Fill(ds, tableName)
End If
Catch ex As Exception
' Si se lanza alguna excepción, se muestra su mensaje correspondiente
MsgBox(ex.Message)
End Try
End Sub
Ahora, para el el siguiente fragmento de código, partimos de la premisa de que tenemos 2 objetos de tipo DataSet cargados: uno con los datos del XML, y otro con los de la base de datos de MSAccess. No voy a entrar en detalle ahora acerca de cómo cargar ambos DataSets, ya que está todo en el proyecto de prueba. El siguiente método hace exactamente lo que pides inserta los datos del XML en la base de datos de MSAccess utilizando objetos de tipo OleDbDataAdapter.
Private Sub btnTransferData1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTransferData1.Click
Try
' Fusionamos los datos de dbDataSet1 con los de xmlDataSet1
dbDataSet1.Merge(xmlDataSet1)
' Creamos los CommandBuilders respectivos a cada DataAdapter
Dim cbMaster As OleDbCommandBuilder = New OleDbCommandBuilder(dbDataAdapterMaster1)
Dim cbDetail As OleDbCommandBuilder = New OleDbCommandBuilder(dbDataAdapterDetail1)
' Creamos las referencias a las tablas que vamos a actualizar
Dim dtMaster As DataTable = dbDataSet1.Tables("Orders")
amp;nbsp; Dim dtDetail As DataTable = dbDataSet1.Tables("OrderDetails")
' Actualizamos las tablas en el origen de datos (nuestra BD de MSAccess)
CType(dbDataAdapterMaster1, OleDbDataAdapter).Update(dtMaster)
CType(dbDataAdapterDetail1, OleDbDataAdapter).Update(dtDetail)
Catch ex As Exception
' Si se lanza alguna excepción, se muestra su mensaje correspondiente
MsgBox(ex.Message)
End Try
End Sub
Como puedes apreciar, hacemos uso del método Merge de la clase DataSet. Este método combina un DataSet especificado y su esquema con el DataSet actual. De esta manera, la siguiente línea de código combina los datos y el esquema de dbDataSet1 con los de xmlDataSet1.
dbDataSet1.Merge(xmlDataSet1)
Finalmente, viene lo más fácil: simplemente tenemos que crear los CommandBuilders respectivos de los DataAdapters de las tablas que deseas actualizar en la base de datos…
Dim cbMaster As OleDbCommandBuilder = New OleDbCommandBuilder(dbDataAdapterMaster1)
Dim cbDetail As OleDbCommandBuilder = New OleDbCommandBuilder(dbDataAdapterDetail1)
… y llamar por último al método Update de los DataAdapters para que transfieran los cambios a la base de datos de MSAccess.
Dim dtMaster As DataTable = dbDataSet1.Tables("Orders")
Dim dtDetail As DataTable = dbDataSet1.Tables("OrderDetails")
No es muy complicado, como puedes apreciar. Más bien, cuando termine el otro escenario (en el que la estructura de las tablas es diferente), lo posteo para que lo revises. Quizás también sea útil.
Espero que haberte ayudado. Y ya sabes, si tienes alguna consulta con el proyecto de demostración, sólo avísame. Bye. Y suerte…
L Intenté adjuntar el proyecto a este post, pero sale un error. Si desean el proyecto de prueba, me escriben a mi coreo. Ok? Yo se los envío. Bye.
Я!©ђ!Є ©Я∆ZΨ |