DontFretBrett
DontFretBrett

Reputation: 1165

OleDbDataAdapter Fill creating duplicate rows

I'm experiencing an issue where I use a data adapter to update and then refill a datatable. After calling the fill method, the row gets duplicated. One ID has the correct (new) ID and the other shows -1 for the ID. The code below works perfect and is the simpler form of what I want my more complex code to do. Cosider the following:

Imports WindowsApplication1.testDataSet
Imports WindowsApplication1.testDataSetTableAdapters
Imports System.Data.OleDb
Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
        Dim DA As New testTableAdapter
        Dim DT As New testDataTable
        DA.Fill(DT)
        Dim NR As testRow = DT.Rows.Add
        NR.SomeText = "Test"
        Dim DA2 As New OleDbDataAdapter("SELECT * FROM test", _
        DA.Connection.ConnectionString)
        Dim CB As New OleDbCommandBuilder(DA2)
        DA2.Update(DT)
        DA.Fill(DT)
        For Each R As testRow In DT.Rows
            Debug.Print(R.ID)
        Next
    End Sub
End Class

The code above works perfect. They key column doesn't show -1, there are no duplicates. Now consider the code below from my application which causes a duplicate row with the key column resulting in -1 right after the last LoadLoadNumbers().

    Dim AccountLoans As IEnumerable(Of LoanNumbersRow) = _
    From L As LoanNumbersRow In LoanNumbers _
    Select L Where L.AccountID = ID

    If Not frmFindLoans.IsDisposed AndAlso _
    frmFindLoans.DialogResult = Windows.Forms.DialogResult.OK Then
        For Each L As LoanNumbersRow In AccountLoans
            If (From R As DataGridViewRow In frmFindLoans.dgvLoans.Rows _
            Select R Where R.Cells("LoanNumber").Value = L.LoanNumber).Count = 0 Then
                If L.IsWhenDeletedNull Then
                    L.WhenDeleted = Now
                    L.DeletedBy = UserName()
                End If
            End If
        Next

        Dim NewLoan As LoanNumbersRow
        Dim FindLoan As IEnumerable(Of LoanNumbersRow)
        For Each R As DataGridViewRow In frmFindLoans.dgvLoans.Rows
            FindLoan = From L As LoanNumbersRow In LoanNumbers.Rows _
            Select L Where L.LoanNumber = R.Cells("LoanNumber").Value And _
            L.AccountID = ID
            If FindLoan.Count = 0 Then
                NewLoan = LoanNumbers.Rows.Add
                NewLoan.AccountID = Acc.AccountID
                NewLoan.LoanNumber = R.Cells("LoanNumber").Value
                NewLoan.LoanBusinessName = R.Cells("LoanBusiness").Value
                NewLoan.LoanBorrower = R.Cells("LoanBorrower").Value
                NewLoan.AddedBy = UserName()
                NewLoan.WhenAdded = Now
            End If
        Next
        Try
            Dim CB As New OleDbCommandBuilder(LoanNumbersAdapter)
            LoanNumbersAdapter.Update(LoanNumbers)
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical, "Error saving loan number data")
            Exit Sub
        End Try

        If Not LoadLoanNumbers() Then Exit Sub
    End If

Other variables and such from a module:

Public LoanNumbersAdapter As OleDbDataAdapter
Public LoanNumbers As New LoanNumbersDataTable
Public Sub InitializeAdapters()
    LoanNumbersAdapter = New OleDbDataAdapter( _
    "SELECT * FROM LoanNumbers WHERE WhenDeleted IS NULL ORDER BY WhenAdded DESC", AccountingConn)
End Sub
Public Function LoadData(ByVal DA As OleDbDataAdapter, ByVal DT As DataTable) As Boolean
    Try
        DA.Fill(DT)
        Return True
    Catch ex As Exception
        MsgBox(ex.Message, MsgBoxStyle.Critical, "Error loading the " & DT.TableName & " table")
        Return False
    End Try
End Function
Public Function LoadLoanNumbers() As Boolean
    Return LoadData(LoanNumbersAdapter, LoanNumbers)
End Function

Why does the simple test at the top work fine, but my actual application create the duplicate row with -1 on the key column? I suppose I could clear the datatable before filling after the update but wouldn't that bog it down once it starts becoming a large table? *BTW: The DB is MS access and it's .NET 3.5

Upvotes: 1

Views: 787

Answers (1)

DontFretBrett
DontFretBrett

Reputation: 1165

This is my duct tape solution :(

''' <summary>
''' Removes any rows where the ID/key column is less than zero
''' </summary>
<Extension()> Public Sub DeleteRelics(ByVal DT As DataTable)
    If DT.PrimaryKey.Count = 0 Then Exit Sub
    For Each R As DataRow In _
    (From Rows As DataRow In DT.Rows _
     Select Rows Where Rows(DT.PrimaryKey.First.ColumnName) < 0)
        R.Delete()
    Next
    DT.AcceptChanges()
End Sub

Upvotes: 1

Related Questions