Quisiera hacer una consulta sobre algo que ya pregunte hace bastante pero no pude resolver. En una aplicación vb.net (winforms) tengo por un lado una tabla de una base de datos access local y por el otro un xml que viene a través de una url. Lo que quiero hacer es que al llamar a un procedimiento actualizar se actualice la base de datos local con la info del xml (altas, bajas y modificaciones). El xml sería una tabla igual con la info actualizada.
Las tablas tienen dos campos id_persona y nombre. Obviamente el campo a actualizar sería nombre.
Lo primero que hago es armar dos datasets cada uno con un datatable y después llamar al metodo merge del dataset. En realidad creo que también los datatables tienen merge, pero de esta forma obtube menos errores.
Hay otra solución que sería borrar toda la tabla cada vez que se actualice pero no queda muy bien.
Código:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click conectaraccess() conexionaccess.Open() ' Creamos un dataset con la tabla (data table) que viene del xml Dim ds_remoto As New DataSet Dim url As String = "http://127.0.0.1/personas/personas.php" Dim myRequest As HttpWebRequest Dim myResponse As HttpWebResponse myRequest = HttpWebRequest.Create(url) myResponse = myRequest.GetResponse Dim myStream As New StreamReader(myResponse.GetResponseStream(), True) Dim xmldoc As New XmlDocument xmldoc.LoadXml(myStream.ReadToEnd) Dim xmlNodeRdr As New XmlNodeReader(xmldoc) ds_remoto.ReadXml(xmlNodeRdr) ' Creamos un dataset igual que el anterior pero con los tipos de datos apropiados en las columnas de la datatable Dim ds_origen As New DataSet Dim dt1 As New DataTable Dim columna As DataColumn Dim fila As DataRow columna = New DataColumn columna.DataType = System.Type.GetType("System.Int32") columna.ColumnName = "id_persona" columna.ReadOnly = True columna.Unique = True dt1.PrimaryKey = New DataColumn() {dt1.Columns("id_persona")} dt1.Columns.Add(columna) columna = New DataColumn columna.DataType = System.Type.GetType("System.String") columna.ColumnName = "nombre" columna.ReadOnly = True columna.Unique = False dt1.Columns.Add(columna) For Each row As DataRow In ds_remoto.Tables(0).Rows fila = dt1.NewRow fila(0) = row(0) fila(1) = row(1) dt1.Rows.Add(fila) Next ds_origen.Tables.Add(dt1) dgv1.DataSource = ds_origen.Tables(0) ' Creamos un tercer dataset con el datatable de la tabla que vamos a actualizar Dim ds_destino As New DataSet Dim dt_destino As New DataTable Dim da_destino As New OleDb.OleDbDataAdapter("select id_persona, nombre from personas", conexionaccess) da_destino.AcceptChangesDuringFill = False da_destino.Fill(ds_destino) ' Hacemos el merge del dataset de destino con el de origen y actualizamos la base de datos Dim cb As New OleDb.OleDbCommandBuilder(da_destino) ds_destino.Merge(ds_origen) da_destino.Update(ds_destino) ds_destino.AcceptChanges() ' Mostramos en datagrid2 los datos ya actualizados (tendrian que ser iguales a los del origen) dgv2.DataSource = ds_destino.Tables(0) ' Mostramos un messagebox para saber si hubo cambios Dim resultado As Boolean = ds_destino.HasChanges MessageBox.Show(resultado) End Sub
Actualmente el error se produce en la linea da_destino.Update(ds_destino) indicando que no se puede ejecutar porque se crearían valores duplicados en el índice. Pero aún sacando esa línea tampoco es posible ver los cambios en los datatables (hay 2 datagrids que muestran cada datatable).
Les agradezco por cualquier sugerencia
Saludos,
Leo