データ アダプタを使用してデータ テーブルを更新してから再入力すると、問題が発生します。fill メソッドを呼び出した後、行が複製されます。一方の ID には正しい (新しい) ID があり、もう一方の ID には -1 が表示されます。以下のコードは完璧に機能し、より複雑なコードで実行したいことをより単純な形で表しています。次のことを検討してください。
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
上記のコードは完璧に機能します。キー列に -1 が表示されず、重複はありません。ここで、私のアプリケーションからの以下のコードを検討してください。これにより、キー列を持つ行が重複し、最後の の直後に -1 になります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
モジュールからの他の変数など:
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
一番上の単純なテストは問題なく動作するのに、実際のアプリケーションではキー列に -1 を指定して重複行を作成するのはなぜですか? 更新後に入力する前にデータテーブルをクリアできると思いますが、大きなテーブルになり始めると、それは行き詰まりませんか? *ところで: DB は MS アクセスで、.NET 3.5 です。