使用重复键更新tableadapter

时间:2013-09-01 17:58:44

标签: sql vb.net datatable sql-update tableadapter

我是更新数据库的新手,显然我并不擅长。

详细信息:

  • 我使用tableadapter(我不知道这是否是最好的方法)在.mdf文件中引用我的数据库
  • 我的表有两列,第一列是Primary Key
  • 该表已有一些行
  • 我在tableadapter中填写:Me.CCListTableAdapter.Fill(Me.HQSdbDataSet.CCList)

我正在尝试做什么:

  1. 我根据CCListTable创建了一个新的数据表:Dim ccDataTable As CCListDataTable = New CCListDataTable
  2. 我使用CsvReader将带有新行(> 3000行)的.csv文件导入到这个新数据表中。我的数据库中已存在行
  3. 然后我尝试将这些新行添加到tableadapter中:

    Me.CCListBindingSource.EndEdit() Me.CCListTableAdapter.Update(ccDataTable)

  4. 但是它不起作用我得SqlException Violation of PRIMARY KEY [...] Cannot insert duplicate key。好的,就像我说我知道有重复的键,但我不想插入这些,但只更新tableadapter与新行。

    这是我创建的用于导入CSV的子代码(如果可以帮助的话):

    Public Sub ImportCSV2Data(ByVal filename As String, ByRef datatable As DataTable, ByVal column2Import() As Integer,
                              ByVal tableAlreadyExist As Boolean)
    
        Dim csvCopy As CachedCsvReader = New CachedCsvReader(New StreamReader(filename), True, ";"c)
        csvCopy.MissingFieldAction = MissingFieldAction.ReplaceByEmpty
    
        Dim headers() As String = csvCopy.GetFieldHeaders
        If column2Import.Length > 0 AndAlso column2Import(0) > -1 Then
            If tableAlreadyExist Then
                While csvCopy.ReadNextRecord()
                    Dim csvRow As DataRow = datatable.NewRow
                    Dim i As Integer = 0
                    For Each column As Integer In column2Import
                        Select Case datatable.Columns(i).DataType.Name
                            Case "String"
                                If String.IsNullOrEmpty(csvCopy(column)) Then
                                    csvRow(i) = ""
                                Else
                                    csvRow(i) = Convert.ToString(csvCopy(column))
                                End If
                            Case "Int32"
                                If String.IsNullOrEmpty(csvCopy(column)) Then
                                    csvRow(i) = DBNull.Value
                                Else
                                    csvRow(i) = Convert.ToInt32(csvCopy(column))
                                End If
                            Case "Double"
                                If String.IsNullOrEmpty(csvCopy(column)) Then
                                    csvRow(i) = DBNull.Value
                                Else
                                    csvRow(i) = Convert.ToDouble(csvCopy(column))
                                End If
                            Case "DateTime"
                                If String.IsNullOrEmpty(csvCopy(column)) Then
                                    csvRow(i) = Nothing
                                Else
                                    csvRow(i) = Convert.ToDateTime(csvCopy(column))
                                End If
                            Case "Boolean"
                                If String.IsNullOrEmpty(csvCopy(column)) Then
                                    csvRow(i) = DBNull.Value
                                Else
                                    csvRow(i) = Convert.ToBoolean(csvCopy(column))
                                End If
                        End Select
                        i += 1
                    Next
                    datatable.Rows.Add(csvRow)
                End While
            Else
                For Each column As Integer In column2Import
                    datatable.Columns.Add(headers(column))
                Next
                While csvCopy.ReadNextRecord()
                    Dim csvRow As DataRow = datatable.NewRow
                    Dim i As Integer = 0
                    For Each column As Integer In column2Import
                        csvRow(i) = csvCopy(column)
                        i += 1
                    Next
                    datatable.Rows.Add(csvRow)
                End While
            End If
        Else
            If tableAlreadyExist Then
                While csvCopy.ReadNextRecord()
                    Dim csvRow As DataRow = datatable.NewRow
                    For i = 0 To csvCopy.FieldCount - 1
                        Select Case datatable.Columns(i).DataType.Name
                            Case "String"
                                If String.IsNullOrEmpty(csvCopy(i)) Then
                                    csvRow(i) = ""
                                Else
                                    csvRow(i) = Convert.ToString(csvCopy(i))
                                End If
                            Case "Int32"
                                If String.IsNullOrEmpty(csvCopy(i)) Then
                                    csvRow(i) = DBNull.Value
                                Else
                                    csvRow(i) = Convert.ToInt32(csvCopy(i))
                                End If
                            Case "Double"
                                If String.IsNullOrEmpty(csvCopy(i)) Then
                                    csvRow(i) = DBNull.Value
                                Else
                                    csvRow(i) = Convert.ToDouble(csvCopy(i))
                                End If
                            Case "DateTime"
                                If String.IsNullOrEmpty(csvCopy(i)) Then
                                    csvRow(i) = Nothing
                                Else
                                    csvRow(i) = Convert.ToDateTime(csvCopy(i))
                                End If
                            Case "Boolean"
                                If String.IsNullOrEmpty(csvCopy(i)) Then
                                    csvRow(i) = DBNull.Value
                                Else
                                    csvRow(i) = Convert.ToBoolean(csvCopy(i))
                                End If
                        End Select
                    Next
                    datatable.Rows.Add(csvRow)
                End While
            Else
                For Each header As String In headers
                    datatable.Columns.Add(header)
                Next
                While csvCopy.ReadNextRecord()
                    Dim csvRow As DataRow = datatable.NewRow
                    For i = 0 To csvCopy.FieldCount - 1
                        csvRow(i) = csvCopy(i)
                    Next
                    datatable.Rows.Add(csvRow)
                End While
            End If
        End If
    End Sub
    

    我错过了什么?

1 个答案:

答案 0 :(得分:0)

以下是解决我的问题的代码:

    'Create a DataTable with the same schema of your DataBase
    Dim ccDataTable As CCListDataTable = New CCListDataTable

    'Import here your csvFile into your new DataTable
    Call ImportCSV2Data(dialog2openFile.FileName, ccDataTable, {0, 2}, True)

    'Merge it with the correct DataTable from your Database (False to recognize the changes)
    Me.HQSdbDataSet.CCList.Merge(ccDataTable, False)

    'Then update your DataBase
    Me.CCListBindingSource.EndEdit()
    Me.CCListTableAdapter.Update(Me.HQSdbDataSet.CCList)

如果在调试模式下关闭应用程序时松动了更改,这是正常的,因为您有两个数据库,一个是应用程序,另一个是调试文件夹,另一个是擦除另一个,当您进入调试模式但是当你启动你的应用程序whitout调试模式就可以了。 其他解决方案:在您的数据库中选择“永不复制”