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

如何用LINQ按ID关联Dictionary<int,Game>与DataGridView行?

LINQ实现DataGridView行与Dictionary的ID关联匹配

场景说明

手头有Dictionary<int, Game>集合(Game为自定义数据类型,无完整构造函数),以及展示部分游戏信息的DataGridView控件。需要用LINQ替代循环遍历行、提取ID对比字典的方式,实现两者按ID关联,获取Dictionary中存储的完整Game对象(包含DataGridView未展示的信息)。

原代码问题分析

你提供的LINQ代码存在逻辑错误:join game in dSourceGames on dSourceGames.Values.Select(x=>x.ID).Contains(...) equals true这种写法不符合LINQ Join的正确逻辑,会导致每次迭代都遍历整个字典的Value集合,效率极低,且无法正确建立关联。

正确实现方式

方式1:LINQ查询表达式(Join语法)

先从DataGridView中提取有效ID,再通过Join关联字典中的Game对象:

// 提取DataGridView选中行的有效ID(假设第3列是ID列,索引为2)
var validGameIds = dgv.SelectedRows
    .Cast<DataGridViewRow>()
    .Where(row => !row.IsNewRow) // 排除新增空行
    .Select(row => 
    {
        // 安全转换ID,避免格式错误导致崩溃
        if (int.TryParse(row.Cells[2].Value?.ToString(), out int id))
            return id;
        return -1;
    })
    .Where(id => id != -1); // 过滤无效ID

// 通过Join关联字典与有效ID,获取匹配的Game对象
List<Game> matchedGames = (from game in dSourceGames.Values
                          join id in validGameIds on game.ID equals id
                          select game).ToList();

方式2:方法链语法(利用Dictionary高效查找)

Dictionary的Key查找是O(1)复杂度,直接通过ID匹配字典Key更高效:

var validGameIds = dgv.SelectedRows
    .Cast<DataGridViewRow>()
    .Where(row => !row.IsNewRow)
    .Select(row => 
    {
        int.TryParse(row.Cells[2].Value?.ToString(), out int id);
        return id;
    })
    .Where(id => id != -1)
    .ToList();

// 直接筛选字典中ID在有效列表中的Game对象
List<Game> matchedGames = dSourceGames.Values
    .Where(game => validGameIds.Contains(game.ID))
    .ToList();

更高效的非LINQ辅助写法

如果选中行数量较多,直接遍历ID从字典取值比遍历整个字典更高效:

var validGameIds = dgv.SelectedRows
    .Cast<DataGridViewRow>()
    .Where(row => !row.IsNewRow)
    .Select(row => 
    {
        int.TryParse(row.Cells[2].Value?.ToString(), out int id);
        return id;
    })
    .Where(id => id != -1);

List<Game> matchedGames = new List<Game>();
foreach (var id in validGameIds)
{
    if (dSourceGames.TryGetValue(id, out var targetGame))
    {
        matchedGames.Add(targetGame);
    }
}

关键注意事项

  • 类型转换安全处理:DataGridView单元格值是object类型,必须用int.TryParse避免空值或格式错误引发异常。
  • 直接复用字典对象:Game无完整构造函数无需新建实例,直接取Dictionary中已存储的Game对象即可,它包含所有完整信息。
  • 区分行集合:若要处理DataGridView所有行而非选中行,将SelectedRows替换为Rows即可,但同样要排除IsNewRow。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:12:49