Привязка поля Long / Int64 к NumericUpDown приводит к исключению OleDbException «Слишком мало параметров» при обновлении

#vb.net #ms-access #oledb

#vb.net #ms-access #oledb

Вопрос:

Я застрял с этой проблемой весь день, так что, возможно, у кого-то есть совет для меня.
Среда: MS Access DB, VB.NET , OleDb-драйвер, MS Access Database Engine 2016.
Я пытаюсь привязать поле Long / Int64 к элементу управления NumericUpDown, но при обновлении я всегда получаю исключение OleDbException «Слишком мало параметров». Я почти уверен, что проблема в длинном поле, потому что, когда я удаляю его из таблицы (и закомментирую код для него), все работает нормально. Я не уверен, что NumericUpDown подходит для этой задачи, но его базовый тип данных — decimal, а decimal имеет гораздо больше места, чем нужно для long . Итак, вот некоторый код:
В dataLayer:

 Private Sub InitializeDataSet()
    Dim LocFields = String.Join("], [", Fields)
    Dim SQL As String = "SELECT [" amp; LocFields amp; "] FROM [" amp; Table amp; "]"

    DAMain = New OleDbDataAdapter(SQL, Connection)
    Using Builder As New OleDbCommandBuilder(DAMain) With {
            .ConflictOption = ConflictOption.OverwriteChanges
        }
        Builder.GetInsertCommand()
        Builder.GetUpdateCommand()
        Builder.GetDeleteCommand()
    End Using

    DS = New DataSet
    DAMain.Fill(DS, Table)
End Sub

Public Sub Update()
    DAMain.Update(DS, Table)  ' <-- Here the exception happens
End Sub

Public ReadOnly Property DataSource As Object
    Get
        Return DS
    End Get
End Property

Public ReadOnly Property DataMember As String
    Get
        Return Table
    End Get
End Property
 

Мы здесь в классе, поэтому переменные:
Таблица = имя таблицы
Поля = список полей в таблице
Соединение = OleDbConnection
DAMain = OleDbDataAdapter
DS = набор данных

В форме:

 Private DL As OleDbDataLayer
Private WithEvents BSource As New BindingSource

Public Sub New(DataLayer As OleDbDataLayer)
    InitializeComponent()

    DL = DataLayer

    BSource.DataSource = DL.DataSource
    BSource.DataMember = DL.DataMember
    BSource.AllowNew = True
    BSource.Sort = DL.OrderBy
    BSource.Position = 0

    InitializeFields()
End Sub

Private Sub DataUpdate()
    BSource.EndEdit()
    DL.Update()
End Sub

Private Sub InitializeFields()
    NUD.Minimum = Long.MinValue
    NUD.Maximum = Long.MaxValue

    Dim Binding As New Binding("Value", BSource, "F_Long")
    AddHandler Binding.Format, AddressOf FormatDBNull
    AddHandler Binding.Parse, AddressOf ParseNumericUpDown
    NUD.DataBindings.Add(Binding)
End Sub

Private Sub FormatDBNull(sender As Object, e As ConvertEventArgs)
    If Convert.IsDBNull(e.Value) Then
        Select Case e.DesiredType
            Case = GetType(Decimal) : e.Value = 0
            Case = GetType(Date) : e.Value = Today
            Case = GetType(Boolean) : e.Value = False
            Case Else
        End Select
    End If
End Sub

Private Sub ParseNumericUpDown(sender As Object, e As ConvertEventArgs)
    Select Case e.DesiredType
        Case = GetType(Byte)
            e.Value = Convert.ToByte(e.Value)
        Case = GetType(Short)
            e.Value = Convert.ToInt16(e.Value)
        Case = GetType(Integer)
            e.Value = Convert.ToInt32(e.Value)
        Case = GetType(Long)
            e.Value = Convert.ToInt64(e.Value)
        Case Else
            ' Do Nothing
    End Select
End Sub
 

Здесь NUD — это элемент управления NumericUpDown, который должен быть очевидным.

Может быть, мне следует использовать другой тип элемента управления? Текстовое поле? MaskedTextBox?

Комментарии:

1. Вы уверены, что DS и Table не равны нулю при попытке обновления?

2. ДА. Я только что протестировал его. Но я был совершенно уверен, потому что, как я уже сказал, код работает нормально, если в таблице нет длинного поля.

3. Я не знаю, может ли это иметь какое-либо отношение к проблеме, но NumericUpDown.Value это десятичное число.

4. @Mary: Да, я знаю. Но десятичное число .NET состоит из 16 байт / 128 бит. Этого должно быть достаточно для хранения 8-байтового / 64-битного числа. Другой аргумент: между тем у меня была точно такая же проблема с другим элементом управления, измененным текстовым полем. Я думаю, проблема в том, что 64-битная длина является совершенно новой в Access .