Question

I'm new in updating databases and apparently I'm not good in it.

Details :

  • I use tableadapter (I don't know if this is the best way) to refer to my database in a .mdf file
  • My table has two columns and the first one is the Primary Key
  • The table has already some rows
  • I fill my tableadapter with : Me.CCListTableAdapter.Fill(Me.HQSdbDataSet.CCList)

What I'm trying to do :

  1. I create a new datatable based on my CCListTable : Dim ccDataTable As CCListDataTable = New CCListDataTable
  2. I import a .csv file with new rows (> 3000 lines) using CsvReader into this new datatable. There are rows who already exists into my database
  3. I try then to add these new rows into the tableadapter with :

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

But it doesn't work and I get an SqlException with Violation of PRIMARY KEY [...] Cannot insert duplicate key. Ok like I said I know there are duplicate keys but I don't want to insert these but only update the tableadapter with the new rows.

Here the sub that I have created to import my CSV (if it can help) :

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

What am I missing?

Was it helpful?

Solution

Here is the code who resolves my issue :

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

If you loose the changes when you close your application in debug mode it is normal because you have two databases one ine your application and the other in the debug folder and the one erase the other when you enter the debug mode but when you launch your application whitout debug mode it is ok. Other solution : In the propriety of you database select 'NEVER COPY'

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top