为什么这个DataAdapter不会将行插入数据库?

时间:2017-09-21 14:40:43

标签: .net vb.net sqldataadapter oledbdatareader

所以我遇到的情况是我使用SqlDataAdapter将行插入SQL Server 2014数据库的表中。

数据来源是Excel电子表格。

使用一些For循环和.Columns.Add和.Rows.Add填充DataTable对象以从Excel工作表复制数据时,插入工作正常。这个工作代码我没有包含在这里。

但是,我正在重构代码以使用OleDbDataReader。这是我的功能:

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

当我调试时,从函数返回的DataTable包含集合中的数据,否则看起来与先前版本的代码中的DataTable相同。以下是.Update数据库的代码。对于这两种情况,此代码未更改

    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

不会抛出异常。调试adp.Update(dt)行没有延迟,就好像查询根本没有执行一样。这是我注意到行/列添加DT和OleDB填充DT之间的唯一区别 - 成功插入数据时有一点延迟时间。

我是否遗漏了DataTable的某些基本功能或属性,或者是在加载期间继承或创建的属性?这是我还没有想到的其他事情吗?为什么我的SqlDataAdapter在数据库中手动创建的DataTableDataTable填充的OleDbReader之间插入数据?

2 个答案:

答案 0 :(得分:2)

每个DataTable跟踪其RowState行,因此在循环中手动添加数据是有效的,因为它们都是Added(它与手动创建{{1}无关它是)。当您从Excel等其他来源加载时,它们添加/新。

如果您使用DataTable填充表格,则可以告诉DataAdapter设置为未更改。这对于将数据从一个数据存储迁移到另一个数据存储非常有用:

RowState

答案 1 :(得分:0)

我遇到了同样的问题,一旦您看到它,解决方案就非常简单...我的数据库在Visual Studio中,其属性“复制到输出目录”设置为“始终复制”,而不是“请勿复制”。因此,每次我运行代码时,都会删除数据库!

解决方案: -修改您的连接字符串,使其直接指向您的数据库 -将您的数据库属性更改为“请勿复制”