.net - net - recorrer dataset c#
¿Por qué este DataAdapter no insertará filas en la base de datos? (1)
Así que tengo una situación en la que estoy usando un SqlDataAdapter para insertar filas en una tabla en una base de datos de SQL Server 2014.
La fuente de los datos es una hoja de cálculo de Excel.
La inserción funciona bien cuando el objeto DataTable se rellena con algunos bucles For y .columnas.Añadir y .Rows.Añadir para copiar los datos de la hoja de Excel. Este código de trabajo no he incluido aquí.
Sin embargo, estoy refactorizando el código para usar un OleDbDataReader. Aquí está mi función:
Private Function FillDataTable(path As String, name As String) As DataTable
Dim fullpath As String = path
Dim wsname As String = name
Dim dt = New DataTable()
Try
Dim connectionstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=''" & fullpath & "'';Extended Properties= ''Excel 8.0;HDR=Yes;IMEX=1''"
Dim commandstring As String = "Select * From " & wsname
Using con As New OleDbConnection(connectionstring)
Using cmd As New OleDbCommand(commandstring, con)
con.Open()
Using dr As OleDbDataReader = cmd.ExecuteReader()
With dt
For Each c In aryFieldList
.Columns.Add(c.FieldName, ConvertType(c.DataType))
Next
.Columns.Add("SubmID")
.Columns("SubmID").DefaultValue = 0
.Columns.Add("S_ORDER")
.Columns("S_ORDER").DefaultValue = 0
.Columns.Add("C_ORDER")
.Columns("C_ORDER").DefaultValue = 0
End With
dt.Load(dr)
End Using
End Using
End Using
Catch ex As Exception
MsgBox(ex.Message)
End Try
Return dt
End Function
Cuando depuro, la DataTable que se devuelve desde la función tiene datos en el conjunto y, de lo contrario, parece ser idéntica a la DataTable de la versión anterior del código. Aquí está el código para. Actualizar la base de datos. Este código no se modifica en ambos casos.
Dim dt = New DataTable()
dt = FillDataTable(fullpath, wsname)
Using cn = New SqlConnection(ConfigurationManager.ConnectionStrings("Connection").ConnectionString)
cn.Open()
Using adp = New SqlDataAdapter()
Dim sb As New StringBuilder
[...StringBuilder code to build the Insert command here...]
Dim cmd As New SqlCommand(sb.ToString, cn)
With adp
.InsertCommand = cmd
.InsertCommand.Parameters.Add("SubmID", SqlDbType.Int, 1, "SubmID")
.InsertCommand.Parameters.Add("S_ORDER", SqlDbType.Int, 1, "S_ORDER")
.InsertCommand.Parameters.Add("C_ORDER", SqlDbType.Int, 1, "C_ORDER")
For Each p In aryFieldList
If p.Excluded = False Then
.InsertCommand.Parameters.Add(p.FieldName, p.DataType, p.Length, p.FieldName)
End If
Next
adp.Update(dt)
End With ''adp
End Using ''adp
End Using ''cn
No se lanzan excepciones. La depuración de la línea adp.Update (dt) no tiene latencia como si la consulta no se ejecutara en absoluto. Esa es la única diferencia que observo entre las Filas / Columnas Añadido DT y el DT OleDB poblado - Hay un ligero tiempo de latencia ya que los datos se insertan con éxito.
¿Me falta algún tipo de funcionalidad básica o propiedad del DataTable
o tal vez una propiedad heredada o creada durante la carga? ¿Es algo más en lo que no he pensado? ¿Por qué mi SqlDataAdapter
inserta datos en la base de datos cuando la fuente es una DataTable
creada manualmente frente a una DataTable
llena por OleDbReader
?
Cada DataTable
rastrea RowState
de sus filas, por lo que la adición manual de datos en un bucle funciona porque todos están Added
(no tiene nada que ver con la creación manual de la DataTable
, son las filas ). Cuando carga desde alguna otra fuente como Excel, no se agregan / nuevos.
Si usa un DataAdapter
para llenar la tabla, puede indicarle que no configure RowState
en Sin cambios. Esto es muy útil para migrar datos de un almacén de datos a otro:
myDA.AcceptChangesDuringFill = False
...
rows = myDA.Fill(xlDT)