vb.net datatable新增数据时改用数组缓存

你想抛弃临时变量(如currentRow/copyrow),直接用List(Of DataRow)存储新增行,同时适配Item属性的读写逻辑 ------ 核心是把Item属性中对currentRow的操作,改为对List中「当前新增行」的操作。我会帮你完整修改代码,确保AddNew1+Item属性 + 批量提交逻辑闭环,且无currentRow依赖。

一、核心修改思路

  1. 新增全局变量NOWID:标记newRows中「当前正在编辑的行索引」(替代currentRow的作用);
  2. AddNew1:向newRows添加新行,并更新NOWID指向最新行;
  3. Item属性:读写newRows(NOWID)对应的字段(而非currentRow);
  4. 移除所有currentRow相关逻辑,彻底基于List管理新增行。

二、完整修改后代码

1. 全局变量调整(新增 NOWID,移除 currentRow)

vb

vbnet 复制代码
' 存储所有新增行(核心)
Private newRows As List(Of DataRow) = New List(Of DataRow)()
' 当前编辑的行索引(替代currentRow,指向newRows中最新行)
Private NOWID As Integer = -1
' 原有变量保留
Private pendingChanges As Boolean = False
Private dt As DataTable
Private adapter As MySqlDataAdapter
Private cmdBuilder As MySqlCommandBuilder
Public ErrInfo As String = ""
Public RecordCount As Long = 0
Public EOF As Boolean = False
Public BOF As Boolean = False
Public AbsolutePosition As Long = 0
2. 修改 AddNew1(直接向 List 加新行,无临时变量)

vb

复制代码
Private Sub AddNew1() ' 每加一条仅向List添加新行,不立即UPDATE
    Try
        ' 1. 向List添加新行(直接newRow,无临时变量)
        Dim newRow As DataRow = dt.NewRow()
        newRows.Add(newRow)
        
        ' 2. 更新NOWID指向最新行(关键:Item属性基于NOWID读写)
        NOWID = newRows.Count - 1
        
        ' 3. 标记有未提交修改
        pendingChanges = True
        
        ErrInfo = ""
    Catch ex As Exception
        ErrInfo = $"新增行失败:{ex.Message}"
    End Try
End Sub
3. 修改 Item 属性(读写 List 中当前行,移除 currentRow)

vb

复制代码
Default Public Property Item(fieldName As String) As Object
    Get
        Try
            ' 核心修改:读取newRows(NOWID)的字段(替代currentRow)
            ' 先判断List是否有行、索引是否有效
            If newRows.Count = 0 Or NOWID < 0 Or NOWID >= newRows.Count Then
                ErrInfo = $"无可用编辑行,索引[{NOWID}]无效"
                Return DBNull.Value
            End If
            Return newRows(NOWID)(fieldName)
        Catch ex As Exception
            ErrInfo = $"读取字段[{fieldName}]失败:{ex.Message}"
            Return DBNull.Value
        End Try
    End Get
    Set(value As Object)
        Try
            ' 核心修改:写入newRows(NOWID)的字段(替代currentRow)
            If newRows.Count = 0 Or NOWID < 0 Or NOWID >= newRows.Count Then
                ErrInfo = $"无可用编辑行,索引[{NOWID}]无效"
                Return
            End If
            
            ' 对List中的行进行编辑(无需BeginEdit/EndEdit,游离行状态不影响)
            Dim targetRow As DataRow = newRows(NOWID)
            ' 空值处理(避免DBNull报错)
            targetRow(fieldName) = If(value Is Nothing, DBNull.Value, value)
            
            pendingChanges = True ' 标记有未提交修改
        Catch ex As Exception
            ErrInfo = $"设置字段[{fieldName}]失败:{ex.Message}"
        End Try
    End Set
End Property
4. 新增批量提交方法(一次性将 List 中所有行加入 dt 并提交)

vb

复制代码
Public Function BatchUpdate() As Long
    Dim updateCount As Long = 0
    Try
        If Not pendingChanges Or newRows.Count = 0 Then
            Return 0 ' 无修改无需提交
        End If
        
        ' 步骤1:遍历List,将所有新增行加入dt(自动跳过自增ID)
        For Each row As DataRow In newRows
            ' 过滤掉空行/无效行
            If row IsNot Nothing Then
                dt.Rows.Add(row)
            End If
        Next
        
        ' 步骤2:批量提交到数据库(复用OpenRecordset2中生成的命令)
        Dim changesDt As DataTable = dt.GetChanges()
        If changesDt IsNot Nothing Then
            updateCount = adapter.Update(changesDt)
            dt.AcceptChanges() ' 重置行状态
        End If
        
        ' 步骤3:清空List和索引,完成提交
        newRows.Clear()
        NOWID = -1
        pendingChanges = False
        ErrInfo = ""
        
        Return updateCount
    Catch ex As MySqlException
        ErrInfo = $"批量提交失败:{ex.Number} - {ex.Message}"
        Return -1
    End Try
End Function

三、关键修改点说明

表格

原逻辑 修改后逻辑 核心原因
依赖currentRow读写字段 依赖newRows(NOWID)读写字段 彻底抛弃临时变量,所有新增行都存在 List 中,NOWID 标记当前编辑行
currentRow.BeginEdit/EndEdit 移除该逻辑 List 中的行是「游离态」,无需显式编辑状态(只有 dt 中的行需要状态管理)
AddNew中复制行引用 AddNew1直接向 List 加新行 无临时变量,List 存储所有新增行,避免引用冲突
单次 Add 后立即 UPDATE 批量提交(BatchUpdate) 符合你 "不用每次 UPDATE" 的诉求,且 List 天然支持批量管理

四、调用示例(VB6 风格)

vb6

复制代码
' 1. 打开记录集
Dim rs As New AdoMysqlRs
rs.OpenRecordset2("SELECT id, name, age FROM users", "users")

' 2. 新增第1行(直接用List管理)
rs.AddNew1
rs("name") = "List新增1" ' 读写newRows(0)
rs("age") = 20

' 3. 新增第2行
rs.AddNew1
rs("name") = "List新增2" ' 读写newRows(1)
rs("age") = 25

' 4. 批量提交所有新增行(仅调用一次)
Dim updateCount As Long = rs.BatchUpdate()
If updateCount > 0 Then
    MsgBox $"成功新增{updateCount}条,无ID重复"
Else
    MsgBox $"提交失败:{rs.ErrInfo}"
End If

五、核心优势(完全匹配你的诉求)

  1. 无临时变量 :彻底抛弃currentRow/copyrow,所有新增行都存在newRows中,NOWID 仅标记当前编辑索引;
  2. 极简 AddNew1:仅 3 行核心代码,直接向 List 加新行,无复杂逻辑;
  3. 批量提交:无需每次 Add 后 UPDATE,最后调用 BatchUpdate 一次性提交,效率更高;
  4. 无 ID 重复:dt.Rows.Add (row) 时,复用之前 OpenRecordset2 中「排除自增 ID」的命令,数据库自动生成 ID。

六、总结

  1. 核心修改:把Item属性中对currentRow的所有操作,替换为对newRows(NOWID)的操作;
  2. 关键补充:新增NOWID索引标记当前编辑行,AddNew1负责向 List 加行并更新索引;
  3. 最终效果:彻底基于 List 管理新增行,无临时变量、无引用冲突、无 ID 重复,且支持批量提交。

这个修改完全按你 "不用临时变量,直接用 List" 的诉求实现,逻辑闭环且极简,适配你连续新增、批量提交的核心需求。

相关推荐
盐水冰几秒前
【烘焙坊项目】后端搭建(14) - 工作台&导出数据报表
java·后端·学习
非凡的小笨鱼4 分钟前
IDEA找不到类编译不通过的解决方案
java·maven·intellij-idea
optimistic_chen5 分钟前
【Vue3入门】自定义指令与插槽详解
linux·运维·服务器·vue.js·前端框架·指令
共享家952711 分钟前
Java入门( 异常 )
java·开发语言·php
牛奶咖啡1314 分钟前
基于Cobbler的系统自动化安装部署——Cobbler的安装部署实践
linux·运维·服务器·cobbler·cobbler的安装配置·cobbler环境检查问题解决·cobbler中导入系统镜像
mounter62517 分钟前
深度解析 RDMA 技术的里程碑:基于 DMA-BUF 的 P2P 直接访问(GPU Direct RDMA 新姿势)
linux·运维·服务器·网络·p2p·kernel
standovon17 分钟前
SQL SERVER 登陆错误:18456
java
大傻^17 分钟前
Spring AI Alibaba 文档智能处理:PDF、Markdown知识入库全链路
java·人工智能·spring·pdf·知识图谱·springai·springaialibaba
恼书:-(空寄26 分钟前
拦截器获取不到 POST 请求 JSON 结构体参数(完整解决方案)
java·spring boot·spring·servlet
Willliam_william32 分钟前
CentOS 7系统中进行时间/时区设置
linux·运维·centos