You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 4.6(VB)游戏网站DataTable权限校验性能优化问询

优化.NET 4.6 VB DataTable权限校验的高效方案

你的问题很典型——当数据量从几百涨到上千级时,逐行遍历DataTable的操作很容易成为性能瓶颈。咱们先拆解下当前代码的核心问题:

  • 每个GameID单独调用CanViewOnGameList/CanEditGameContent等方法,大概率存在重复的数据库查询或缓存访问,1500次调用就是1500次IO开销
  • 逐行调用dr.Delete()和AcceptChanges(),DataTable的行删除是O(n)操作,频繁触发会导致大量内存移位和状态变更
  • 每行单独更新字段后立即AcceptChanges(),没必要的状态同步会增加额外开销

下面是几个针对性的优化方案,按实现难度和性能提升排序:

1. 批量获取权限集合(最优先优化)

把多次单GameID的权限查询,改成一次性获取当前用户所有有权限的GameID集合,从根源减少IO次数。

示例代码:

' 第一步:批量获取当前用户的所有权限GameID集合
Dim viewableGameIDs As New HashSet(Of Integer)(GetUserViewableGameIDs(currentUserID))
' 合并CanEditGameContent和CanEditGameInfo的权限到同一个集合
Dim editableGameIDs As New HashSet(Of Integer)(GetUserEditableGameIDs(currentUserID))
Dim playableGameIDs As New HashSet(Of Integer)(GetUserPlayableGameIDs(currentUserID))

' 第二步:复制原表并批量处理
Dim tmpGameList As DataTable = fullGameList.Copy

' 先筛选出不可见的游戏并批量删除
Dim nonViewableRows() As DataRow = tmpGameList.Select($"gameID NOT IN ({String.Join(",", viewableGameIDs)})")
For Each dr As DataRow In nonViewableRows
    dr.Delete()
Next

' 批量更新可编辑和可玩状态
For Each dr As DataRow In tmpGameList.Rows
    dr("isEditableGame") = If(editableGameIDs.Contains(CInt(dr("gameID"))), 1, 0)
    dr("isPlayableGame") = If(playableGameIDs.Contains(CInt(dr("gameID"))), 1, 0)
Next

' 最后统一提交所有变更
tmpGameList.AcceptChanges()
myGameList = tmpGameList

说明:GetUserViewableGameIDs等方法需要调整为批量查询,比如用SQL的WHERE userID = @ID直接返回所有符合条件的gameID列表,而不是单ID查询。

2. 用DataView筛选替代逐行删除

如果不需要保留原表结构的修改,用DataView的RowFilter可以直接过滤出可见游戏,避免删除行的开销:

' 先拼接可见GameID的字符串
Dim viewableIDsStr As String = String.Join(",", viewableGameIDs)
Dim dv As New DataView(fullGameList)
dv.RowFilter = $"gameID IN ({viewableIDsStr})"

' 把过滤后的DataView转成新的DataTable
Dim tmpGameList As DataTable = dv.ToTable()

' 再批量更新权限状态
For Each dr As DataRow In tmpGameList.Rows
    dr("isEditableGame") = If(editableGameIDs.Contains(CInt(dr("gameID"))), 1, 0)
    dr("isPlayableGame") = If(playableGameIDs.Contains(CInt(dr("gameID"))), 1, 0)
Next
myGameList = tmpGameList

3. 改用强类型集合+LINQ(长期优化方向)

DataTable本质是弱类型的,遍历和修改的性能不如强类型对象集合。可以先把fullGameList转成List(Of GameModel),用LINQ操作后再转回DataTable:

示例:

' 定义强类型游戏模型
Public Class GameModel
    Public Property GameID As Integer
    Public Property IsEditableGame As Integer
    Public Property IsPlayableGame As Integer
    ' 其他游戏字段(如游戏名称、图标等)...
End Class

' 把DataTable转换为强类型集合
Dim gameList As List(Of GameModel) = fullGameList.AsEnumerable().Select(Function(dr) New GameModel With {
    .GameID = CInt(dr("gameID")),
    ' 映射其他需要的字段
}).ToList()

' 用LINQ筛选可见游戏并更新权限状态
Dim filteredList = gameList.Where(Function(g) viewableGameIDs.Contains(g.GameID)).Select(Function(g)
    g.IsEditableGame = If(editableGameIDs.Contains(g.GameID), 1, 0)
    g.IsPlayableGame = If(playableGameIDs.Contains(g.GameID), 1, 0)
    Return g
End Function).ToList()

' 转回DataTable(如果需要绑定UI)
myGameList = filteredList.ToDataTable()

注:ToDataTable()可以自己实现一个扩展方法,.NET 4.6支持简单的反射转换逻辑,也可以借助成熟的第三方库完成。

4. 减少不必要的AcceptChanges调用

原代码中每行修改后都调用dr.AcceptChanges(),这完全没必要——只需要在所有行修改/删除完成后,统一调用tmpGameList.AcceptChanges()即可,能减少大量的状态同步开销。


内容的提问来源于stack exchange,提问作者SkyeBoniwell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:43:12