recorrer net llenar for ejemplo desde .net vb.net sqldataadapter oledbdatareader

.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)